3

我正在爲移動應用程序製作後端,並使用Django和Userena進行用戶管理。我做了登錄並使用Django REST框架註冊,一切正常。我現在唯一需要做的就是實現「忘記密碼」功能。我想使用Userena中已經實現的一個,但是即使在使用dectororator後,我也無法擺脫「CSRF令牌丟失或不正確」的錯誤。我在做什麼?csrf_exempt不能與django驗證碼一起工作

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請求時,會在cookie中CSRF令牌,你可以然後發送您的POST請求。

如果您堅持豁免該觀點:我認爲問題在於CSRF保護適用於password_reset視圖的方式。它由csrf_protect明確裝飾。

要仔細看看問題,我們假設original_password_reset_viewpassword_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等效距離CsrfViewMiddleware一個middleware-turned-decoratorcsrf_exempt另一方面simply sets csrf_exempt=True對其論點。因此,由外部csrf_protect表示的中間件在視圖上看到csrf_exempt=True值,並禁用其CSRF投影。它否定外部csrf_protect。所以我們有:

csrf_protect(original_password_reset_view) 

該視圖仍然受到保護。基本上,沒有任何理智的方法。 (一種瘋狂的方式:編寫一箇中間件,爲該特定的URL設置request.csrf_processing_done = True。不要這樣做...)

+0

感謝您的解釋! – kahlo