2012-03-13 114 views
31

我正在關注Django 1.3 Web Development。和登錄,我收到以下錯誤CSRF驗證失敗。請求中止。在Django上

Forbidden (403) 
CSRF verification failed. Request aborted. 
Help 
Reason given for failure: 
    CSRF token missing or incorrect. 

這是我的settings.py包括應用程序。正是這本書說的應該是這樣。

INSTALLED_APPS = (
    'django.contrib.auth', 
    'django.contrib.contenttypes', 
    'django.contrib.sessions', 
    'django.contrib.sites', 
    'django.contrib.messages', 
    'django.contrib.staticfiles', 
    # Uncomment the next line to enable the admin: 
    'django.contrib.admin', 
    # Uncomment the next line to enable admin documentation: 
    # 'django.contrib.admindocs', 
    'djangocricket.Cricket', 
    'djangocricket.cms' 
) 

書上說,它應該包含,django.contrib.auth.views.login ..和我包括它在

urlpatterns = patterns('', 
    # Examples: 
    url(r'^$', 'djangocricket.Cricket.views.index', name='default'), 
    url(r'^user/(\w+)/$', 'djangocricket.Cricket.views.user_home', name='user home'), 
    url(r'^login/$', 'django.contrib.auth.views.login'), 
    # url(r'^djangocricket/', include('djangocricket.foo.urls')), 

    # Uncomment the admin/doc line below to enable admin documentation: 
    #url(r'^admin/doc/', include('django.contrib.admindocs.urls')), 

    # Uncomment the next line to enable the admin: 
    url(r'^news/', 'djangocricket.cms.views.index', name='index'), 
    #url(r'^news/(?P<slug>[^\.]+).html', 'djangocricket.cms.views.detail', name='get_single_news_item'), 
    url(r'^admin/', include(admin.site.urls)), 
) 

和我的註冊/ login.html的副本...從書中粘貼。它應該這樣做。

<html> 
<head> 
    <title>Django Bookmarks - User Login</title> 
</head> 
<h1>User Login</h1> 
{% if form.errors %} 
    <p>Your username and password didn't match. 
     Please try again.</p> 
{% endif %} 
<form method="post" action="."> 
    <p><label for="id_username">Username:</label> 
     {{ form.username }}</p> 
    <p><label for="id_password">Password:</label> 
     {{ form.password }}</p> 
    <input type="hidden" name="next" value="/" /> 
    <input type="submit" value="login" /> 
</form> 
</body> 
</html> 

我在想什麼?

回答

52

您需要將{% csrf_token %}模板標記添加爲您的Django模板中form元素的子元素。

這樣,模板將呈現一個隱藏元素,其值設置爲CSRF標記。當Django服務器收到表單請求時,Django將驗證該令牌是否與表單中呈現的值匹配。這對確保POST請求(即數據更改請求)源自可信的客戶端會話很有必要。

欲瞭解更多信息,請查看Django的文檔: https://docs.djangoproject.com/en/dev/ref/csrf/

這裏是跨站請求僞造攻擊的概述: https://www.owasp.org/index.php/CSRF

+0

謝謝,這有助於。 – debuggerpk 2012-03-13 22:01:52

+3

感謝您的鏈接 – 2012-11-13 13:14:05

7

如果使用csrf_token模板標籤,但不會改變任何東西,檢查CSRF_COOKIE_DOMAIN設置。你應該在開發環境中設置None

+2

檢查'CSRF_COOKIE_SECURE'以及如果您的開發服務器沒有ssl。 – Mark 2015-07-01 13:26:41

4

只想通過該主題提供更多信息。如果它發生在你身上,並且你確定該令牌被注入到表單中,並且視圖函數正確地處理了所有內容,但問題仍然存在。確保沒有JavaScript代碼禁用輸入字段。經過幾個小時的調試後,發現我終於意識到這一點。

<input type="hidden" name="csrfmiddlewaretoken" value="pHK2CZzBB323BM2Nq7DE2sxnQoBG1jPl" disabled=""> 
+0

好點;當提交表單時,「disabled」表單元素的值不會發送到服務器。 – 2016-03-14 21:35:21

5

我有同樣的問題。我在添加{%csrf_token%}時解決了這個問題。最後,我的代碼是這樣的:

<form id='formulario2' method='post' action='> 
     <h3>Enter:</h3> 
     {% csrf_token %} 


    <input id="id_mesaje" name="mesaje" type="email" placeholder="E-mail"/> 
    <input type='submit' name="boton2" value='Suscribete' style="display:inline-block;background-color: #80e174; "/> 
</form> 
0

嗨只需在表單中使用{%csrf_token%}。這對我來說已經解決了。那麼爲什麼我們要使用跨站點請求僞造? 好吧,答案很簡單,它只是在您的網頁中添加了另一個安全層,從而任何惡意用戶都無法使用錯誤的令牌驗證請求。

相關問題