search

Home  >  Q&A  >  body text

Axios request does not send expected cookie header to Django server

I'm trying to upload a file to a Django server using Axios post requests in a React app. The server expects a CSRF cookie in the request header.

This request already contains all the methods I can find for setting cookies. Pass document.cookie, set withCredential: true, and specify the Cookie header.

This is my Axios request:

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

This is my Django view:

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

Also, I believe I have the relevant Django settings set correctly in 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'

How do I ensure that the CSRF cookie is included in the request header or otherwise meets CSRF requirements? To be sure, the route works if we add @csrf_exempt to the view, so it really should be a CSRF issue.

P粉285587590P粉285587590240 days ago334

reply all(1)I'll reply

  • P粉463824410

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

    You just need to include the token in formData. No header or cookie manipulation required:

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

    Tip: Whenever you are unsure whether cookies, headers, etc. are being sent, check the Network tab in your browser's developer tools. If you see them in the Request Headers section of the request, then they are being sent, which means the problem is on the server side. In this case, for multipart/form-data Django requires the csrfmiddlewaretoken token in the form field. For application/json requests, you can use the X-CSRFToken header.

    reply
    0
  • Cancelreply