Как я могу использовать базовую аутентификацию с django_webtest для доступа к Django REST framework?

У меня возникают проблемы при публикации данных в некоторые представления, которые используют Django REST Framework в моих тестах. Я использую django_webtest для тестирования моего пользовательского API. Я столкнулся с проблемой со следующим кодом:

class UserApiTest(WebTest):

    def setUp(self):
        AdminFactory()

    def test_accessing_user_list_shows_one_user(self):
        user_list = self.app.get('/quickstart/users/', user='admin')
        assert_that(user_list.json, has_entry('count', 1))

    def test_posting_new_user_returns_url_for_user_detail(self):
        post_data = {'username': 'john', 'email': 'john.doe@example.com'} 
        user_create = self.app.post('/quickstart/users/', post_data, user='admin')
        url = 'http://localhost:80/quickstart/users/2/'
        assert_that(user_create.json, has_entry('url', url))

Проблема в том, что я получаю ошибку CSRF при запуске второго теста. Глядя на документацию по Django REST Framework, я прочитал, что ошибка CSRF возникает только при использовании аутентификации на основе сеансов. Итак, я решил попробовать базовую аутентификацию, которая согласно документации Django требует только установки REMOTE_USER переменная окружения:

class UserApiTest(WebTest):

    extra_environ = {'REMOTE_USER': 'admin'}

    def setUp(self):
        AdminFactory()

    def test_accessing_user_list_shows_one_user(self):
        user_list = self.app.get('/quickstart/users/')
        assert_that(user_list.json, has_entry('count', 1))

    def test_posting_new_user_returns_url_for_user_detail(self):
        post_data = {'username': 'john', 'email': 'john.doe@example.com'} 
        user_create = self.app.post('/quickstart/users/', post_data)
        url = 'http://localhost:80/quickstart/users/2/'
        assert_that(user_create.json, has_entry('url', url))

Это работало хуже, так как пользователь даже не был авторизован для просмотра этих страниц (то есть доступ к URL вернул 403).

У меня вопрос: как правильно настроить базовую аутентификацию с помощью django_webtest?

1 ответ

Решение

После работы над проблемой, я обнаружил, что мне нужно передать полные основные заголовки аутентификации, а не только REMOTE_USER, Это связано с тем, что Django REST Framework анализирует базовую аутентификацию в своих BasicAuthentication бэкенд.

class UserApiTest(WebTest):                                                     

    auth_password = base64.encodestring('admin:default').strip()               
    extra_environ = {                                                           
        'AUTH_TYPE': 'Basic',                                                   
        'HTTP_AUTHORIZATION': 'Basic {}'.format(auth_password),                 
        'REMOTE_USER': 'admin'}                                                

    def setUp(self):                                                            
        AdminFactory()                                                          

    def test_accessing_user_list_shows_one_user(self):                          
        user_list = self.app.get('/quickstart/users/')                          
        assert_that(user_list.json, has_entry('count', 1))                      

    def test_posting_new_user_returns_url_for_user_detail(self):                
        post_data = {'username': 'john', 'email': 'john.doe@example.com'}     
        user_create = self.app.post('/quickstart/users/', post_data)            
        url = 'http://localhost:80/quickstart/users/2/'                         
        assert_that(user_create.json, has_entry('url', url))

Кроме того, по умолчанию вы должны убедиться, что любой пользователь, которого вы создаете в своих тестах, имеет is_staff флаг установлен на да. Конечно, если вы установили Django REST для других прав доступа, чем вы должны убедиться, что эти права установлены правильно.

Я надеюсь, что это помогает кому-то.

Другие вопросы по тегам