Вход в Django APIClient не работает

У меня проблемы с аутентификацией с помощью API Django Rest Framework в модульных модульных тестах. Система работает должным образом при доступе к ней через браузер. Однако я получаю статус HTTP 401 при отправке запроса на размещение в следующий класс в следующей конечной точке:

class UserDetail(RetrieveModelMixin, DestroyModelMixin, UpdateModelMixin, GenericViewSet):
    authentication_classes = (BasicAuthentication, TokenAuthentication)
    permission_classes = IsAuthenticated,
    queryset = CustomUser.objects.all()
    serializer_class = UserSerializer

Тест ниже выглядит следующим образом:

class AccountTests(APITestCase):

    def setUp(self):
        self.user = CustomUser.objects.create_user(email="[email protected]", password="password1", is_staff=True)
        self.user.save()
        self.user = CustomUser.objects.get(email="[email protected]")
        self.client = APIClient()

    def test_add_name(self):
        self.client.login(email="[email protected]", password='password1')
        url = reverse('customuser-detail', args=(self.user.id,))
        data = {'first_name': 'test', 'last_name': 'user'}

        self.client.login(email="[email protected]", password='password1')
        response = self.client.put(url, data, format='json')

        self.assertEqual(response.status_code, status.HTTP_200_OK)

При печати response.data я получаю:

{u'detail': u'Authentication credentials were not provided.'}

Метод client.login(...) возвращает значение true, но учетные данные не прикреплены к заголовку. Мои эксперименты с классами разрешений IsAuthenticated имели request.user = AnonymousUser. В классе BasicAuthentication auth = None.

Я что-то упустил в отношении использования BasicAuth в settings.py? Или даже в самом тесте?

Спасибо.


person mingles    schedule 29.05.2016    source источник
comment
вы решили проблему?   -  person Ajax    schedule 24.07.2016


Ответы (2)


Во-первых, {u'detail': u'Authentication credentials were not provided.'} происходит, когда учетные данные, которые вы «предоставляете», не совпадают с моделями. (Я думаю, что это плохое сообщение об ошибке)

Итак, вы должны установить пароль пользователя методом set_password() из-за шифрования.

self.user = CustomUser.objects.create_user(email="[email protected]", is_staff=True)
self.user.set_password("password1")
self.user.save()

или вы можете использовать force_login() для тестирования.

self.client.force_login(
    user=User.objects.first(),
    backend='django.contrib.auth.backends.ModelBackend' # one of your AUTHENTICATION_BACKENDS
)
person Seung Woon Maz Lee    schedule 19.07.2017

Возможно, вам придется использовать метод force_authenticate() для входа в систему,

def test_add_name(self):
    self.client.force_authenticate(self.user)        
    ........

Вы можете подумать о том, чтобы переписать свой тестовый пример, может быть, примерно так,

class AccountTests(APITestCase):

    def setUp(self):
        self.user = CustomUser.objects.create_user(email="[email protected]", password="password1", is_staff=True)
        self.client = APIClient()

    def test_add_name(self):
        self.client.force_authenticate(self.user)

        url = reverse('customuser-detail', args=(self.user.id,))
        data = {'first_name': 'test', 'last_name': 'user'}
        response = self.client.put(url, data, format='json')

        self.assertEqual(response.status_code, status.HTTP_200_OK)
person zaidfazil    schedule 19.07.2017