2017-01-13 10 views
0

У меня вопрос, где я могу войти в успешно, но все последующие запросы показывают, какCSRF токен неудачу на второй пост Джанго Rest Framework

"detail":"CSRF Failed: CSRF token missing or incorrect." 

Я понятия не имею, что я делаю неправильно, я просмотрели документы Docs, документы DRF, отключили аутентификацию, чтобы проверить URL-адрес и найти старые сообщения SO по этому вопросу.

Вот основная функция с прикрепленной основной информацией

def will_fail(): 
    CURRENT_URL = 'http://127.0.0.1:8000/{}' 
    session = requests.Session() 
    response = session.get(CURRENT_URL.format('api-auth/login/')) 
    csrftoken = response.cookies['csrftoken'] 

    first_response = session.post(CURRENT_URL.format('api-auth/login/'), 
            data={'username': 'itsme', 'password': 'password'}, 
            headers={'X-CSRFToken': csrftoken}) 

    response = session.post(CURRENT_URL.format('api-v1/languages/'), 
          params={'name': "French", "audio_base": "adpifajsdpfijsdp"}, 
          headers={'X-CSRFToken': csrftoken}) 

first_response (логин):

URL - 'http://127.0.0.1:8000/api-v1/' 
Text - {"languages":"http://127.0.0.1:8000/api-v1/languages/","phrases":"http://127.0.0.1:8000/api-v1/phrases/","stats":"http://127.0.0.1:8000/api-v1/stats/"} 
Status - <Response [200]> 

ответа (добавить языка):

URL - 'http://127.0.0.1:8000/api-v1/languages/?audio_base=adpifajsdpfijsdp&name=French' 
Text - {"detail":"CSRF Failed: CSRF token missing or incorrect."} 
Status - <Response [403]> 

Настройка очень простая так как я только начал с этого:

THIRD_PARTY_APP = [ 
    'rest_framework.authtoken', 
    'rest_framework', 
] 
REST_FRAMEWORK = { 
    'DEFAULT_AUTHENTICATION_CLASSES': (
     'rest_framework.authentication.SessionAuthentication', 
    ), 
    'DEFAULT_PERMISSION_CLASSES': (
     'rest_framework.permissions.IsAuthenticated', 
    ) 
} 

Вот информация URL, который также является довольно общим

from training.views import LanguageViewSet, PhraseViewSet, PhraseStatsViewSet 

router = DefaultRouter() 
router.register(r'languages', LanguageViewSet) 
router.register(r'phrases', PhraseViewSet) 
router.register(r'stats', PhraseStatsViewSet) 

urlpatterns = [ 
    url(r'^admin/', admin.site.urls), 
    url(r'^api-auth/', include('rest_framework.urls', namespace='rest_framework')), 
    url(r'^api-v1/', include(router.urls, namespace='api')) 
] 

Я использую ModelSerializers и ModelViewSets, я не отменяю любые методы и включены все поля.

EDIT: Я уже пытался обновить маркер, как хорошо, но это дало мне исключение KeyError -

Traceback (most recent call last): 
    File "C:/Users/Me/PycharmProjects/proj/post_data.py", line 70, in <module> 
    will_fail() 
    File "C:/Users/Me/PycharmProjects/proj/post_data.py", line 62, in will_fail 
    csrftoken = first_response.cookies['csrftoken'] 
    File "C:\Users\Me\Envs\proj\lib\site-packages\requests\cookies.py", line 329, in __getitem__ 
    return self._find_no_duplicates(name) 
    File "C:\Users\Me\Envs\proj\lib\site-packages\requests\cookies.py", line 400, in _find_no_duplicates 
    raise KeyError('name=%r, domain=%r, path=%r' % (name, domain, path)) 
KeyError: "name='csrftoken', domain=None, path=None" 

ответ

1

Проблема в том, что ваш первый запрос регистрирует пользователя в Django вращает маркер, когда вы войти:.

Почему может после сбоя пользователь сталкивается с отказом проверки CSRF?

Из соображений безопасности токены CSRF поворачиваются каждый раз, когда пользователь входит в систему. Любая страница с формой, сгенерированной до входа в систему, будет иметь старый недопустимый токен CSRF и должна быть перезагружена. Это может произойти, если пользователь использует кнопку «Назад» после входа в систему или если они входят в другую вкладку браузера.

Токен, который вы используете в следующих запросах, является токеном, который использовался до его поворота. Вам нужно получить новый токен из файла cookie после запроса на вход.

Кроме того, requests прозрачно следует за перенаправлением и возвращает последний ответ. Поскольку второй ответ (возможно) не использует токен, он не устанавливается как файл cookie. Вы можете использовать allow_redirects=False, чтобы получить первый запрос, а затем получить новый токен из этого запроса. В качестве альтернативы вы можете отправить новый запрос GET на страницу, использующую токен в теле ответа, тогда токен будет отправлен как файл cookie.

... 

first_response = session.post(CURRENT_URL.format('api-auth/login/'), 
           data={'username': 'itsme', 'password': 'password'}, 
           headers={'X-CSRFToken': csrftoken}, 
           allow_redirects=False) 

# Get the new token 
newcsrftoken = first_response.cookies['csrftoken'] 

response = session.post(CURRENT_URL.format('api-v1/languages/'), 
         params={'name': "French", "audio_base": "adpifajsdpfijsdp"}, 
         headers={'X-CSRFToken': newcsrftoken}) 
0

Вы, вероятно, не с помощью сессий с запросами, которые будут держать исходные куки отклика для следующих запросов ,

DRF говорит вам о том, как CSRF работает с ФПИ на http://www.django-rest-framework.org/topics/ajax-csrf-cors/#csrf-protection

+0

Я не уверен, что понимаю, я неправильно использую сеансы? Я делаю запрос получения, чтобы вытащить токен csrf, а затем передать его в последующие почтовые запросы. –

Смежные вопросы