Django-Rest-Framework JWT 单元测试说“未提供身份验证”

Posted

技术标签:

【中文标题】Django-Rest-Framework JWT 单元测试说“未提供身份验证”【英文标题】:Django-Rest-Framework JWT Unit Test Saying "No Authentication Provided" 【发布时间】:2015-09-25 19:53:44 【问题描述】:

当我尝试进行单元测试时,我得到了错误:

"detail":"未提供身份验证凭据。"

但是,我使用的是 django-rest-framework-jwt,它希望将 Web 令牌放在标题中作为“授权:JWT”。我对来自我的网站的工作、接受的数据包做了一个wireshark,它有 Authorization: JWT 标头。我当前的请求也被拒绝了。我不知道为什么它失败了。

添加 force_authenticate 允许它运行,但我想测试我的权限。

这是来自文档的参考:

现在,为了访问受保护的 api url,您必须包含 授权:JWT 标头。

django-rest-framework-jwt documentation

这是来自 PyCharm 的请求:

'REQUEST_METHOD': 'PATCH', 
'CONTENT_TYPE': 'application/json; charset=None', 
'CONTENT_LENGTH': 74, 
'PATH_INFO': '/api/v1/members/5', 
'QUERY_STRING': '', 
'Authorization': 'JWT eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VybmFtZSI6InVzZXIiLCJlbWFpbCI6ImVtYWlsQGdtYWlsLmNvbSIsInVzZXJfaWQiOjUsImV4cCI6MTQzNzUzOTE4MH0.cGcXw9srOYgbeICdbMw8Ey_ya9eBRD-ptRsGwd2jzlk', 
'wsgi.input': <django.test.client.FakePayload object at 0x106689748>

代码如下:

class ModifyTest(APITestCase):
    """ Test modifying users, to include member_profile
    """
    username = 'user'
    password = 'passwd'
    token = 0
    user_id = 0

    def setUp(self):
        data = 'username': self.username,
                'password': self.password,
                'email': 'email@gmail.com'
        url = reverse('members:auth-user-create')
        response = self.client.post(url, data, format='json')
        self.user_id = response.data['id']

        data = 'username': self.username,
                'password': self.password
        url = reverse('token_auth')
        response = self.client.post(url, data, format='json')
        self.token = response.data['token']

    def test_auth_user_info(self):
        data = 'id': str(self.user_id),
                'password': self.password,
                'email': 'email@gmail.com',
                'username': self.username,
                
        url = reverse('members:auth-user-detail', kwargs='pk': self.user_id)
        response = self.client.patch(url, data, Authorization='JWT ' + self.token, format='son')
        self.assertEqual(response.status_code, 200)

更新: 在逐步完成身份验证时,我意识到我的视图没有使用正确的身份验证类。以下是我的设置...

REST_FRAMEWORK = 
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        #'rest_framework.authentication.BasicAuthentication',
        #'rest_framework.authentication.SessionAuthentication',
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
    ),

REST_FRAMEWORK = 
    'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',)

我的看法:

class AuthUserDetail(generics.RetrieveUpdateDestroyAPIView):
    permission_classes = (IsOwnerOrAdmin,)
    queryset = get_user_model().objects.all()
    serializer_class = AuthUserModelSerializer

但是,当调用视图时,我的调试器中的权限类是:

<class 'rest_framework.authentication.SessionAuthentication'>, 
<class 'rest_framework.authentication.BasicAuthentication'>

所以将这一行添加到我的视图中可以修复它:

authentication_classes = (JSONWebTokenAuthentication,)

但是选择默认类时不需要这样做...有什么想法为什么不使用默认值?

【问题讨论】:

执行curl -H "Authorization: JWT &lt;your_token&gt;" http://localhost:8000/api/v1/members/5/时会发生什么? 是的......所以下面是我在这个问题上浪费太多时间的原因......希望没有其他人犯这个错误。我花了很长时间才注意到,因为它只是修改的一个因素,而且我正在分享一个允许任何身份验证的视图......不聪明,应该完成卷曲并节省自己的时间。谢谢 是的,我遇到了同样的错误,我添加了 autentication_classes =[JSONWebTokenAuthentication]...谢谢! 【参考方案1】:

我想通了...我不知道我有两个部分 REST_FRAMEWORK 所以很明显第二个部分是覆盖第一个删除我的默认值...新的设置文件:

REST_FRAMEWORK = 
    'DEFAULT_PERMISSION_CLASSES': (
        'rest_framework.permissions.IsAuthenticated',
    ),
    'DEFAULT_AUTHENTICATION_CLASSES': (
        'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
    ),
    'DEFAULT_FILTER_BACKENDS': ('rest_framework.filters.DjangoFilterBackend',)

【讨论】:

以上是关于Django-Rest-Framework JWT 单元测试说“未提供身份验证”的主要内容,如果未能解决你的问题,请参考以下文章

jwt认证

django-rest-framework之 json web token方式完成用户认证

Django + Auth0 JWT 身份验证拒绝解码

在视图或消费者中使用 jwt 令牌验证并获取用户

jwt 令牌授权无法与自定义角色一起正常工作

nginx的问题。如何使用jwt(Django)对API进行身份验证调用?