La requête Axios n'envoie pas l'en-tête de cookie attendu au serveur Django
P粉285587590
P粉285587590 2024-03-28 11:18:33
0
1
342

J'essaie de télécharger un fichier sur un serveur Django à l'aide de la requête de publication Axios dans une application React. Le serveur attend un cookie CSRF dans l'en-tête de la requête.

Cette demande contient déjà toutes les méthodes que je peux trouver pour paramétrer les cookies. Via document.cookie,设置withCredential: true,并指定Cookie en-tête.

Voici ma demande 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)
}

Voici ma vue 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})

De plus, je pense que les paramètres Django pertinents sont correctement configurés dans settings.py :

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'

Comment garantir que les cookies CSRF sont inclus dans les en-têtes de requête ou répondent aux exigences CSRF ? Bien sûr, l'itinéraire fonctionne si nous ajoutons @csrf_exempt à la vue, cela devrait donc vraiment être un problème CSRF.

P粉285587590
P粉285587590

répondre à tous(1)
P粉463824410

Il vous suffit d'emballer le jeton formData. Aucune manipulation d'en-tête ou de cookie requise :

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)
}

Conseil : chaque fois que vous n'êtes pas sûr que des cookies, des en-têtes, etc. soient envoyés, vérifiez l'onglet Réseau dans les outils de développement de votre navigateur. Si vous les voyez dans la partie "Request Headers" de la requête, alors ils sont envoyés, ce qui signifie que le problème vient du côté serveur. Dans ce cas, pour l'en-tête multipart/form-data Django 需要 csrfmiddlewaretoken 表单字段中的令牌。对于 application/json 请求,您可以使用 X-CSRFToken.

Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal