简体   繁体   中英

Specifying basic authentication credentials for a Django REST framework API client

I'm trying to run some tests to go with the Django REST tutorial (see source code ). I got a solution working using the APIClient 's .force_authenticate method, but I'd prefer to construct the credentials more explicitly. I've tried the following:

import json
import base64

from django.contrib.auth.models import User
from django.test import TestCase

from rest_framework.test import APITestCase, force_authenticate

from snippets.models import Snippet

class SnippetTestCase(APITestCase):
    def setUp(self):
        self.username = 'john_doe'
        self.password = 'foobar'
        self.user = User.objects.create(username=self.username, password=self.password)
        # self.client.force_authenticate(user=self.user)

        credentials = base64.b64encode(f'{self.username}:{self.password}'.encode('utf-8'))
        self.client.credentials(HTTP_AUTHORIZATION='Basic {}'.format(credentials))

    def test_1(self):
        response = self.client.post('/snippets/', {'code': 'Foo Bar'}, format='json')
        self.assertEqual(response.status_code, 201)

This test passed with the commented-out line with .force_authenticate , but fails in its current form, which I based on Using Basic HTTP access authentication in Django testing framework :

Kurts-MacBook-Pro:rest-framework-tutorial kurtpeek$ python manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
F
======================================================================
FAIL: test_1 (tutorial.tests.SnippetTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/Users/kurtpeek/Documents/source/rest-framework-tutorial/tutorial/tests.py", line 23, in test_1
    self.assertEqual(response.status_code, 201)
AssertionError: 403 != 201

----------------------------------------------------------------------
Ran 1 test in 0.022s

FAILED (failures=1)

Apparently, the authentication is not working because I'm getting a 403 Forbidden error. Any ideas on how to fix this?

try:

self.client.credentials(HTTP_AUTHORIZATION='Basic {}'.format(credentials.decode('utf-8'))

Alternatively, you may also consider this

I finally solved the issue by simply calling the self.client 's login method with the username and password of the self.user defined in the setUp method:

import json

from django.contrib.auth.models import User
from django.test import TestCase

from rest_framework.test import APITestCase

from snippets.models import Snippet

class SnippetTestCase(APITestCase):
    def setUp(self):
        self.username = 'john_doe'
        self.password = 'foobar'
        self.user = User.objects.create_user(username=self.username, password=self.password)

    def test_1(self):
        self.client.login(username=self.username, password=self.password)
        response = self.client.post('/snippets/', {'code': 'Foo Bar'}, format='json')
        self.assertEqual(response.status_code, 201)

This test passes:

Kurts-MacBook-Pro:rest-framework-tutorial kurtpeek$ python manage.py test
Creating test database for alias 'default'...
System check identified no issues (0 silenced).
.
----------------------------------------------------------------------
Ran 1 test in 0.259s

OK
Destroying test database for alias 'default'...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM