python - 当我为 Django Rest Framework API 测试我的 POST 路由时,即使已登录,它也会返回未经过身份验证的 401
问题描述
当我尝试为我的 Django Rest Framework API 测试我的 Create/POST 路由时,我收到了 401 的响应状态代码,错误详情告诉我ErrorDetail(string=u'Authentication credentials were not provided.', code=u'not_authenticated')
。奇怪的是,当我检查 is_authenticated 时,Django 告诉我我已通过身份验证。
有谁知道可能是什么原因造成的?下面提供的所有相关代码。
# test_api.py
def authorise_user_and_test_is_authenticated(self, user_id):
"""
Log in user and test this is successful
"""
user = User.objects.get(pk=user_id)
self.client.login(username=user.username, password=user.password)
authorised_user = auth.get_user(self.client)
return self.assertTrue(user.is_authenticated())
def test_create_project(self):
'''
When given valid parameters a project is created.
'''
user = User.objects.get(username="user_001")
self.authorise_user_and_test_is_authenticated(user.id) # pass of authenication and auth testing to method, when tested with is_authenicated() it returns true.
response = self.client.post('/api/user/{0}/project/create/'.format(user.id),
json.dumps({"model_name": "POSTed Project",
"description": "Project tested by posting",
"shared_users[]": [2]
}),
content_type='application/json')
self.assertEqual(response.status_code, 201)
# views.py
class MyCreateView(generics.GenericAPIView):
pass
serializer_class = FerronPageCreateAndUpdateSerializer
def get_queryset(self):
return User.objects.filter(pk=self.kwargs.get('user'))
def post(self, request, format=None, **kwargs):
# This dictionary is used to ensure that the last_modified_by field is always updated on post to be the current user
print request.data
request_data = {
'user': request.user.id,
'model_name': request.data['model_name'],
'description': request.data['description'],
'last_modified_by': request.user.id,
'shared_users': request.data.getlist('shared_users[]', [])
}
serializer = FerronPageCreateAndUpdateSerializer(data=request_data)
if serializer.is_valid():
serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# settings.py
REST_FRAMEWORK = {
# Use Django's standard `django.contrib.auth` permissions,
# or allow read-only access for unauthenticated users.
'DEFAULT_PERMISSION_CLASSES': [
'rest_framework.permissions.DjangoModelPermissionsOrAnonReadOnly'
],
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.TokenAuthentication',
'rest_framework.authentication.SessionAuthentication'
),
}
# url matcher
url(r'^user/(?P<user>\d+)/project/create/$', MyCreateView.as_view(), name='create-project')
class FerronPageCreateAndUpdateSerializer(serializers.ModelSerializer):
shared_users = serializers.PrimaryKeyRelatedField(many=True, queryset=User.objects.all(), read_only=False)
description = serializers.CharField(max_length=300, trim_whitespace=True, required=False, allow_blank=True)
class Meta:
model = Project
fields = [
'pk',
'user',
'data',
'model_name',
'description',
'created_at',
'date_modified',
'shared_users',
'last_modified_by'
]
解决方案
原来问题出在方法self.client.login(username=user.username, password=user.password)
内部authorise_user_and_test_is_authenticated(self, user_id)
。
问题是我使用的密码是我已经创建的用户实例。这意味着当我给出论点时password=user.password
,我试图使用已经散列的密码登录。我需要做的是使用原始未散列的密码版本登录,例如password='openseasame'
.
推荐阅读
- symfony - Symfony 4 模态形式
- javascript - 按距离给定的升序对点数组进行排序
- c# - CheckPasswordASync 总是返回 false
- python - 在等待方法tkinter中等待一秒钟
- c++ - 如何在 C++ 中修复“没有匹配的函数来调用...”?
- python - 用于匹配 Python 列表中的特定模式的正则表达式
- amazon-web-services - S3 向用户授予对象访问权限
- laravel - Vanilo 的自定义产品属性放在哪里?
- sass - 使用设计系统作为源在各自的项目目录中编译 sass 文件
- android - 如何将视图相对于非同级视图居中?