【问题标题】:How to test authentication using REST Framework JWT?如何使用 REST Framework JWT 测试身份验证?
【发布时间】:2016-01-09 01:19:19
【问题描述】:

基于 JWT 的身份验证在使用从移动设备和“高级休息客户端”发送的 POST 请求时效果很好,但是在使用 Django 测试客户端时它会失败。 客户端在请求时成功接收到令牌,但在尝试使用该令牌访问受限视图时得到以下响应。

“未提供身份验证凭据。”

测试用例:

def test_get_token(self):
        response = self.client.post("/auth/api/get_token/", {"username": "Heffalumps", "password": "Woozles"})
        self.assertEqual(response.status_code, 200, "The token should be successfully returned.")

        response_content = json.loads(response.content.decode('utf-8'))
        token = response_content["token"]

        # The following request fails
        response = self.client.post("/auth/api/authenticated/", {}, Authorization='JWT ' + token)
        response_content = json.loads(response.content.decode('utf-8'))

        self.assertEqual(response_content["authenticated"], "mooh", "The user should be able to access this endpoint.")

来自测试客户端的传出请求:

受限视图:

class RestrictedView(APIView):
    permission_classes = (permissions.IsAuthenticated, )
    authentication_classes = (JSONWebTokenAuthentication, )

    def post(self, request):

        response_data = json.dumps({"authenticated": "mooh"})

        return HttpResponse(response_data, content_type='application/json')

我在测试用例中遗漏了什么吗?

【问题讨论】:

    标签: python django django-rest-framework jwt


    【解决方案1】:

    另外请记住,当您创建用户时,您必须使用哈希版本的密码。例如:

    User(email='TestUser@email.io', password=make_password('TestPassword')))

    (Using djangos password hashers)

    在拨打/auth/api/get_token/ 时,您必须使用明文密码。例如:

    response = self.client.post("/auth/api/get_token/", {'email': 'TestUser@email.io', 'password': 'TestPassword'})

    我花了一段时间才发现请求响应了'non_field_errors': ['Unable to log in with provided credentials.'],因为我在创建用户时没有使用哈希器。

    【讨论】:

      【解决方案2】:

      请注意,当通过 OAuth2 使用 JWT 时,以下代码会创建身份验证凭据:

      self.client.post("/auth/api/authenticated/", {}, HTTP_AUTHORIZATION='Bearer {0}'.format(token))
      

      然而,Django Rest Framework 包含用于验证请求的脚手架: http://www.django-rest-framework.org/api-guide/testing/#forcing-authentication

      此外,这里还有一些有趣的测试: https://github.com/jpadilla/django-jwt-auth/blob/master/tests/test_mixins.py

      【讨论】:

        【解决方案3】:

        好的,以下似乎已经解决了这个问题:

        代替:

        response = self.client.post("/auth/api/authenticated/", {}, Authorization='JWT ' + token)
        

        我不得不写:

        response = self.client.post("/auth/api/authenticated/", {}, HTTP_AUTHORIZATION='JWT {}'.format(token))
        

        身份验证现在也可以通过 Django 测试客户端进行。

        【讨论】:

        • 谢谢!拯救了我的一天。
        • 我使用带有令牌身份验证的 Django Rest API,需要将其更改为:response = self.client.get('/api/someurl', {}, HTTP_AUTHORIZATION='Token {}'。格式(self.token))
        猜你喜欢
        • 2015-06-01
        • 2019-01-01
        • 2018-07-04
        • 2015-09-25
        • 2020-04-10
        • 2021-06-19
        • 2016-01-08
        • 2019-11-20
        • 2017-08-15
        相关资源
        最近更新 更多