簡體   English   中英

使用 Python 請求未在 Django 中設置 CSRF 令牌

[英]CSRF token not set in Django with Python Request

我正在嘗試使用 Python-Request 從普通 Python 腳本向 Django 視圖發送 POST 請求。 django 視圖不是@login_required ,所以除了我的 JSON 數據之外,我唯一需要發送的是 CSRF 令牌,這是我嘗試過的:

token = session.get('http://127.0.0.1:8000/myview/view')
data = json.dumps({'test': 'value'})
session.post('http://127.0.0.1:8000/myview/myview',
             data={
                 'csrfmiddlewaretoken': token,
                 'data': data})

django 視圖應該只接收請求並將其打印到我的控制台:

def myview(request):
    if request.method == 'POST':
        data = request.POST.get('data')
        print(json.loads(data))
        print('received.')

    response = HttpResponse(get_token(request))
    return response

我當前代碼的問題是我的控制台會拋出一個log: WARNING - Forbidden (CSRF token missing or incorrect.) 我不能使用@csrf_exempt ,因為我需要它盡可能安全。 有什么建議嗎? 提前致謝!

為什么用戶登錄后會遇到CSRF驗證失敗?

出於安全原因,每次用戶登錄時都會輪換 CSRF 令牌。 任何頁面

登錄前生成的表單將具有舊的、無效的 CSRF 令牌,需要重新加載。 如果用戶在登錄后使用后退按鈕或登錄不同的瀏覽器選項卡,則可能會發生這種情況。

這也適用於 cookie。 登錄后,django 會向客戶端發送一個新的 csrf cookie。 這將存儲在 client.cookies 中並替換舊的。 django 服務器不會保留舊令牌的任何記錄,因此這就是您收到“CSRF 令牌丟失或不正確”的原因。 回復。

您可以像以前一樣從 request.cookies['csrftoken'] 訪問新令牌。

import requests

LOGIN_URL = 'http://127.0.0.1:8000/myview/view'
request = requests.session()
request.get(LOGIN_URL)
# Retrieve the CSRF token first
csrftoken = request.cookies['csrftoken']
r1 = request.post(LOGIN_URL, headers={'X-CSRFToken': csrftoken},
                          allow_redirects=False))
new_csrftoken = r1.cookies['csrftoken']
data = json.dumps({'test': 'value'})
payload = {'csrfmiddlewaretoken': new_csrftoken,'data':data }

實際上,您可以直接使用客戶端 cookie。 這首先可以避免這個錯誤。 當您使用 requests.session() 時,Requests 會為您跟蹤 cookie。

try :
    r2 = request.post('http://127.0.0.1:8000/myview/myview', data=payload, headers={'X-CSRFToken': r1.cookies['crsftoken']})
except :
    print('error expected')

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM