当我测试Django Rest Framework API的POST路由时,即使登录,它也会返回未通过身份验证的401

时间:2018-10-28 02:09:44

标签: python django django-rest-framework

当我尝试为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'

]

1 个答案:

答案 0 :(得分:0)

最后发现问题出在self.client.login(username=user.username, password=user.password)方法内的authorise_user_and_test_is_authenticated(self, user_id)

问题是我使用的密码是我已经创建的用户的实例。这意味着当我给参数password=user.password时,我试图使用已经被散列的密码登录。我需要做的是使用原始未加密的密码登录,例如password='openseasame'