3

Я делаю backend для мобильного приложения и используя Django с Userena для управления пользователями. Я сделал вход и зарегистрировался с использованием инфраструктуры Django REST, и все работает нормально. Единственное, что мне нужно сделать сейчас - это реализовать функциональность «забыть пароль». Я хотел использовать уже реализованный из Userena, но я не могу избавиться от ошибки «CSRF-токен, отсутствующий или некорректный», даже после использования dectorator csrf_exempt. Что я делаю?csrf_exempt не работает с django auth

urls.py

from django.contrib.auth.views import password_reset 
from django.views.decorators.csrf import csrf_exempt 
... 
urlpatterns = patterns(
    '', 
    url(r'^password/mobile/reset/$', 
     csrf_exempt(password_reset), 
     {'template_name': 'userena/password_reset_form.html', 
     'email_template_name': 'userena/emails/password_reset_message.txt', 
     'extra_context': {'without_usernames': userena_settings.USERENA_WITHOUT_USERNAMES} 
     }, 
     name='userena_password_mobile_reset'), 
) 

passowrd_reset_form.html

{% extends 'userena/base_userena.html' %} 
{% load i18n %} 

{% block title %}{% trans "Reset password" %}{% endblock %} 

{% block content %} 
<form action="" method="post"> 
    <fieldset> 
    <legend>{% trans "Reset Password" %}</legend> 
    {% csrf_token %} 
    {{ form.as_p }} 
    </fieldset> 
    <input type="submit" value="{% trans "Send password" %}" /> 
</form> 
{% endblock %} 
+0

Если вы посмотрите на запрос, отправленный этой формой, например, в средствах разработки вашего браузера (Вкладка «Сеть» ...), является токеном CSRF, включенным в отправленные данные? Исключение представления из защиты CSRF не является хорошей идеей, так как позволяет злоумышленникам сбросить пароль ваших пользователей. – sk1p

+0

вы также можете добавить views.py, просто хотите проверить декоратор csrf_exempt. –

+0

@sawangupta csrf_excempt применяется в его конфигурации url: 'csrf_exempt (password_reset)' – sk1p

ответ

6

Если вы делаете запрос GET перед вывешивать в целях сброса пароля, вы получите маркер CSRF в печенье, которое вы можете затем отправьте запрос POST.

Если вы настаиваете на освобождении зрения: я думаю, проблема заключается в том, как защита CSRF применяется к виду password_reset. Он явно оформлен csrf_protect.

Чтобы более подробно рассмотреть проблему, допустим, что original_password_reset_view is password_reset без csrf_protect. В принципе, вы делаете это:

csrf_exempt(csrf_protect(original_password_reset_view)) 
# ^^ your code 
#   ^^ the decorator in django.contrib.auth.views 

И добавив в эффект от CsrfViewMiddleware, мы получаем эквивалент

csrf_protect(csrf_exempt(csrf_protect(original_password_reset_view))) 

csrf_protect просто middleware-turned-decorator от CsrfViewMiddleware. csrf_exempt с другой стороны simply sets csrf_exempt=True по своим аргументам. Таким образом, промежуточное ПО, представленное внешним csrf_protect, видит значение csrf_exempt=True в представлении и отключает его проекцию CSRF. Он отрицает внешнийcsrf_protect. Таким образом, мы имеем:

csrf_protect(original_password_reset_view) 

Вид по-прежнему защищен. В принципе, нет разумного пути. (Безумный способ: написать промежуточное программное обеспечение, которое устанавливает request.csrf_processing_done = True для этого конкретного URL-адреса. Не делайте этого ...)

+0

Спасибо за объяснение! – kahlo

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