解決Django提交表單報(bào)錯:CSRF token missing or incorrect的問題
1、在Django提交表單時報(bào)錯:Django提交表單報(bào)錯:
CSRF token missing or incorrect
具體報(bào)錯頁面如下:

2、有道詞典翻譯后如下:
通常,當(dāng)存在真正的跨站點(diǎn)請求偽造時,或者Django的CSRF機(jī)制沒有被正確使用時,就會出現(xiàn)這種情況。至于郵遞表格,你須確保:
您的瀏覽器正在接受cookie。
視圖函數(shù)將一個請求傳遞給模板的呈現(xiàn)方法。
在模板中,每個POST表單中都有一個{% csrf_token %}模板標(biāo)記,目標(biāo)是一個內(nèi)部URL。
如果您沒有使用CsrfViewMiddleware,那么您必須在任何使用csrf_token模板標(biāo)簽的視圖以及那些接受POST數(shù)據(jù)的視圖上使用csrf_protect。
該表單有一個有效的CSRF令牌。在登錄另一個瀏覽器選項(xiàng)卡或登錄后單擊back按鈕之后,您可能需要使用表單重新加載頁面,因?yàn)榈卿浐罅钆茣D(zhuǎn)。
您將看到這個頁面的幫助部分,因?yàn)樵贒jango設(shè)置文件中有DEBUG = True。將其更改為False,將只顯示初始錯誤消息。
您可以使用CSRF_FAILURE_VIEW設(shè)置自定義這個頁面。
3、解決辦法:
(1)、確定項(xiàng)目底下的settings.py文件,是否存在django.middleware.csrf.CsrfViewMiddleware:
MIDDLEWARE = [ 'django.middleware.security.SecurityMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', 'django.middleware.common.CommonMiddleware', 'django.middleware.csrf.CsrfViewMiddleware', 'django.contrib.auth.middleware.AuthenticationMiddleware', 'django.contrib.messages.middleware.MessageMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', ]
(2)、如果確定settings.py文件有配置了,還是報(bào)錯,就要在form表單底下加一行代碼:
{% csrf_token %}
這樣應(yīng)該就不會報(bào)上面錯誤了,以上內(nèi)容僅供學(xué)習(xí)參考,謝謝!
補(bǔ)充知識:Django中csrf token驗(yàn)證原理
我多年沒維護(hù)的博客園,有一篇初學(xué)Django時的筆記,記錄了關(guān)于django-csrftoekn使用筆記,當(dāng)時幾乎是照抄官網(wǎng)的使用示例,后來工作全是用的flask。博客園也沒有維護(hù)。直到我的博客收到了如下評論,確實(shí)把我給問倒了,而且我也仔細(xì)研究了這個問題。
1. Django是怎么驗(yàn)證csrfmiddlewaretoken合法性的?
2. 每次刷新頁面的時候<input>中的csrf的value都會更新,每次重復(fù)登錄的時候cookie的csrf令牌都會刷新,那么這兩個csrf-token有什么區(qū)別?

image.png
CSRF(Cross Site Request Forgery protection),中文簡稱跨站請求偽造。
django 第一次響應(yīng)來自某個客戶端的請求時,會在服務(wù)器端隨機(jī)生成一個 token,把這個 token 放在 cookie 里。然后每次 POST 請求都會帶上這個 token,
這樣就能避免被 CSRF 攻擊。
這樣子看起來似乎沒毛病,但是評論中的第三個問題,每次刷新頁面,form表單中的token都會刷新,而cookie中的token卻只在每次登錄時刷新。我對csrftoken的驗(yàn)證方式起了疑問,后來看了一段官方文檔的解釋。
When validating the ‘csrfmiddlewaretoken' field value, only the secret, not the full token, is compared with the secret in the cookie value. This allows the use of ever-changing tokens. While each request may use its own token, the secret remains common to all.
This check is done by CsrfViewMiddleware.
官方文檔中說到,檢驗(yàn)token時,只比較secret是否和cookie中的secret值一樣,而不是比較整個token。
我又有疑問了,同一次登錄,form表單中的token每次都會變,而cookie中的token不便,django把那個salt存儲在哪里才能保證驗(yàn)證通過呢。
直到看到源碼。
def _compare_salted_tokens(request_csrf_token, csrf_token):
# Assume both arguments are sanitized -- that is, strings of
# length CSRF_TOKEN_LENGTH, all CSRF_ALLOWED_CHARS.
return constant_time_compare(
_unsalt_cipher_token(request_csrf_token),
_unsalt_cipher_token(csrf_token),
)
def _unsalt_cipher_token(token):
"""
Given a token (assumed to be a string of CSRF_ALLOWED_CHARS, of length
CSRF_TOKEN_LENGTH, and that its first half is a salt), use it to decrypt
the second half to produce the original secret.
"""
salt = token[:CSRF_SECRET_LENGTH]
token = token[CSRF_SECRET_LENGTH:]
chars = CSRF_ALLOWED_CHARS
pairs = zip((chars.index(x) for x in token), (chars.index(x) for x in salt))
secret = ''.join(chars[x - y] for x, y in pairs) # Note negative values are ok
return secret
token字符串的前32位是salt, 后面是加密后的token, 通過salt能解密出唯一的secret。
django會驗(yàn)證表單中的token和cookie中token是否能解出同樣的secret,secret一樣則本次請求合法。
同樣也不難解釋,為什么ajax請求時,需要從cookie中拿取token添加到請求頭中。
網(wǎng)上有不少關(guān)于django csrf token驗(yàn)證原理的文章都是錯的,是因?yàn)樗麄兏静恢纁srf-token的結(jié)構(gòu)組成,我也是卡在第三條評論那.然后看了官方文檔,和CsrfViewMiddleware中間件源碼然后才恍然大悟。
以上這篇解決Django提交表單報(bào)錯:CSRF token missing or incorrect的問題就是小編分享給大家的全部內(nèi)容了,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Python3進(jìn)行表格數(shù)據(jù)處理的示例詳解
數(shù)據(jù)處理是一個當(dāng)下非常熱門的研究方向,通過對于大型實(shí)際場景中的數(shù)據(jù)進(jìn)行建模,可以用于預(yù)測下一階段可能出現(xiàn)的情況。本文就來聊聊Python3進(jìn)行表格數(shù)據(jù)處理的相關(guān)操作,需要的可以參考一下2023-03-03
基于python3監(jiān)控服務(wù)器狀態(tài)進(jìn)行郵件報(bào)警
這篇文章主要介紹了基于python3監(jiān)控服務(wù)器狀態(tài)進(jìn)行郵件報(bào)警,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2019-10-10
Python分聃?之?dāng)?shù)字雨加入潘周聃運(yùn)動曲線的詳細(xì)過程
相信各位同學(xué)最近一定被潘周聃刷屏和洗腦了,互聯(lián)網(wǎng)上也出現(xiàn)了這種各樣的模仿者,下面通過本文給大家分享Python分聃之?dāng)?shù)字雨加入潘周聃運(yùn)動曲線,需要的朋友可以參考下2022-05-05
django 前端頁面如何實(shí)現(xiàn)顯示前N條數(shù)據(jù)
這篇文章主要介紹了django 前端頁面如何實(shí)現(xiàn)顯示前N條數(shù)據(jù)。具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-03-03
Python3實(shí)現(xiàn)轉(zhuǎn)換Image圖片格式
本篇文章給大家分享了Python3實(shí)現(xiàn)在線轉(zhuǎn)換Image圖片格式的功能以及相關(guān)實(shí)例代碼,有興趣的朋友參考下。2018-06-06
Flask Paginate實(shí)現(xiàn)表格分頁的使用示例
flask_paginate是Flask框架的一個分頁擴(kuò)展,用于處理分頁相關(guān)的功能,本文就來介紹一下Flask Paginate實(shí)現(xiàn)表格分頁的使用示例,感興趣的可以了解一下2023-11-11
詳解PyTorch預(yù)定義數(shù)據(jù)集類datasets.ImageFolder使用方法
這篇文章主要為大家介紹了PyTorch預(yù)定義數(shù)據(jù)集類datasets.ImageFolder使用方法詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-04-04
解決出現(xiàn)Incorrect integer value: '''' for column ''id'' at row 1
這篇文章主要介紹了解決出現(xiàn)Incorrect integer value: '' for column 'id' at row 1的問題的相關(guān)資料,希望通過本文能幫助到大家,讓大家遇到這樣的問題及時的解決,需要的朋友可以參考下2017-10-10

