搜尋

首頁  >  問答  >  主體

Axios 請求未將預期的 cookie 標頭髮送到 Django 伺服器

我正在嘗試在 React 應用程式中使用 Axios post 請求將檔案上傳到 Django 伺服器。伺服器期望請求標頭中包含 CSRF cookie。

該請求已包含我能找到的所有用於設定 cookie 的方法。透過document.cookie,設定withCredential: true,並指定Cookie頭。

這是我的 Axios 請求:

const onSubmit = async (data) => {
    const formData = new FormData()
    formData.append('file', data.file[0])

    const csrftoken = getCookie('csrftoken');
    document.cookie = `csrftoken=${csrftoken}`

    const res = await axiosInstance.post('/upload/', formData, {
        timeout: 0,
        headers: {
            'Cookie': `csrftoken=${csrftoken}`, 
            'Content-Type': 'multipart/form-data',
            'x-csrftoken': csrftoken,
        },
        withCredentials: true,
    })

    console.log(res)
}

這是我的 Django 視圖:

def upload_file(request):
    form = UploadFileForm()
    if request.method == 'POST':
        form = UploadFileForm(request.POST, request.FILES)

        if form.is_valid():
            file_id = save_file_to_database(request.FILES['file'])
            response = JsonResponse({'id': file_id}, status=201)
            return response
        else:
            response = HttpResponse({'message': 'Upload failed'}, status=400)
            return response

    return render(request, 'upload.html', {'form': form})

另外,我相信我已經在 settings.py 中正確設定了相關的 Django 設定:

CORS_ORIGIN_WHITELIST = (
    "http://localhost:8000",
    "http://127.0.0.1:5173",
)

CSRF_TRUSTED_ORIGINS = [
    "http://127.0.0.1:5173"
]

SESSION_COOKIE_SAMESITE = 'None'

如何確保 CSRF cookie 包含在請求標頭中或以其他方式滿足 CSRF 要求?可以肯定的是,如果我們將 @csrf_exempt 添加到視圖中,該路由就可以工作,所以它確實應該是一個 CSRF 問題。

P粉285587590P粉285587590243 天前344

全部回覆(1)我來回復

  • P粉463824410

    P粉4638244102024-03-29 10:02:40

    您只需將令牌包含在 formData 中。無需標頭或 cookie 操作:

    const onSubmit = async (data) => {
        const formData = new FormData()
        formData.append('file', data.file[0])
        formData.append('csrfmiddlewaretoken', getCookie('csrftoken'));
    
        const res = await axiosInstance.post('/upload/', formData, {
            timeout: 0,
            headers: {
                'Content-Type': 'multipart/form-data',
            },
            withCredentials: true,
        })
    
        console.log(res)
    }
    
    

    提示:每當您不確定是否正在傳送 cookie、標頭等時,請檢查瀏覽器開發工具中的網頁標籤。如果您在請求的「請求標頭」部分看到它們,那麼它們正在被傳送,這表示問題出在伺服器端。在本例中,對於 multipart/form-data Django 需要 csrfmiddlewaretoken 表單欄位中的令牌。對於 application/json 請求,您可以使用 X-CSRFToken 標頭。

    回覆
    0
  • 取消回覆