简体   繁体   English

Django 测试客户端 POST 请求,出现 403 错误

[英]Django Testing Client POST Request, Getting 403 Error

I'm trying to test some client requests for the first time, and I am able to successfully sent a POST request to register a new user.我第一次尝试测试一些客户端请求,并且能够成功发送 POST 请求来注册新用户。 However, when I attempt to login, I receive a 403 error and I'm not sure what is causing it... thinking maybe I've missed something in the test?但是,当我尝试登录时,我收到一个 403 错误,我不确定是什么原因造成的......我想也许我在测试中遗漏了一些东西? I am successfully able to login on my deployed app.我能够成功登录我部署的应用程序。

Error message:错误信息:

======================================================================
FAIL: test_user_login_POST (jwt_auth.tests.TestUsers)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/jz/Development/BetterCred/jwt_auth/tests.py", line 32, in test_user_login_POST
    self.assertEqual(response.status_code, 202)
AssertionError: 403 != 202

----------------------------------------------------------------------
Ran 3 tests in 1.416s

Test:测试:

def setUp(self):
        User.objects.create(
            username = 'JohnnyBoy',
            password = 'pass123!',
            email = "email@gmail.com",
            first_name = "John",
            last_name = "Smith",
        )

def test_user_login_POST(self):
        req_url = reverse('user-login')
        login_details = {
            'username': 'JohnnyBoy',
            'password': 'pass123!'
        }

        response = self.client.post(req_url, login_details, content_type="application/json")

        print(response)
        self.assertEqual(response.status_code, 202)

View (I added code=404 to see if my test was hitting that point, but doesn't seem like it):查看(我添加了 code=404 以查看我的测试是否达到了这一点,但似乎不是这样):

class LoginView(APIView):

    # POST - Login a user and return a token
    def post(self, request):

        username = request.data.get('username')
        password = request.data.get('password')

        try:
            user_to_login = User.objects.get(username = username)
        except User.DoesNotExist:
            raise PermissionDenied('Invalid credentials.', code = 404)
        
        if not User.check_password(user_to_login, password):
            raise PermissionDenied('Invalid credentials.', code = 404)
        
        exp_time = datetime.now() + timedelta(weeks = 1)

        token = jwt.encode(
            {
                'sub': user_to_login.id,
                'exp': int(exp_time.strftime('%s')),
            }, 
            settings.SECRET_KEY,
            'HS256'
        )

        return Response(
            { 
                'message': f'Welcome back {user_to_login.first_name}!',
                'token': token,
            },
            status.HTTP_202_ACCEPTED
        )

I appreciate any suggestions or tips我感谢任何建议或提示

You cannot simply request.data.get from json POST request.您不能简单地从json POST请求中request.data.get You have to process data first.您必须先处理数据。

Change:改变:

username = request.data.get('username')
password = request.data.get('password')

To this:对此:

import json
from django.http import JsonResponse
(...)

try:
    json_data = json.loads(request.body)
except json.JSONDecodeError:
    return JsonResponse({"error": "Content is not JSON serializable"}, status=400)

username = json_data.get('username')
password = json_data.get('password')

After reading the Django testing documentation further, I learned that I can't simply set the password of the User I created for testing directly using 'password': 'pass123,'.在进一步阅读了 Django 测试文档后,我了解到我不能简单地设置我为测试创建的用户的密码,直接使用“密码”:“pass123”。 but instead need to use,set_password().但需要使用 set_password()。 as the password needs to be stored in a correctly hashed format因为密码需要以正确的散列格式存储

Snippet of the relevant Django documentation below for anyone who runs into a similar issue as me in the future:以下相关 Django 文档的片段,供将来遇到与我类似问题的任何人使用:

Remember that if you want your test user to have a password, you can't set the user's password by setting the password attribute directly – you must use the set_password() function to store a correctly hashed password.请记住,如果您希望您的测试用户拥有密码,则不能通过直接设置密码属性来设置用户的密码——您必须使用 set_password() function 来存储正确的散列密码。 Alternatively, you can use the create_user() helper method to create a new user with a correctly hashed password.或者,您可以使用 create_user() 辅助方法创建具有正确散列密码的新用户。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM