当我尝试做单元a测试时,我得到错误:
"detail":"未提供身份验证凭据。"
然而,我正在使用django-rest-framework-jwt,它希望将web令牌放在标题处为"Authorization: JWT"。我做了一个wireshark工作,接受包从我的网站,它有授权:JWT头。我现在的请求也被拒绝了。我不明白为什么会失败。
添加force_authenticate允许它运行,但我想测试我的权限。下面是文档中的引用:
django-rest-framework-jwt文档现在,为了访问受保护的api url,您必须包含授权:JWT头。
这是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',)
}
And my view:
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,)
但是,如果选择了默认类,就不需要这样做了…知道为什么不使用默认值吗?
我明白了…我没有意识到我有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',)
}