uneeb meer
uneeb meer

Reputation: 973

Cookies not being sent with Axios

I have a form built on Nuxt/vuejs. On the backend side on django the CSRF protection is enabled which now expects two things in the Api call X-CSRFToken as a header and csrftoken as a Cookie , I tested the Api by calling the Api through Postman which works fine but in case Of Vue it is not sending the Cookies with post request let me show you my code

Axios post request

const headers = {
    "X-CSRFToken": "some token",
    "Cookie": "csrftoken=some token",
}
await axios.post(`onboarding/first-name-last-name-email/`, {
    "first_name": "uneeb2",
    "last_name": "sad",
    "email": "[email protected]"
}, {
    headers: headers
}, {
    withCredentials: true
})

I have also tried Fetch is it also having the same issue

fetch(
  'https://staging.goqube.io/api/onboarding/first-name-last-name-email/',
  { credentials: 'include' ,method: "POST",headers:headers} // could also try ''
).then(res => {
  if (res.ok) return res.json()
  // not hit since no 401
})

I also tried setting default values in axios it worked for header key but the cookie is still not sent

axios.defaults.xsrfCookieName = 'csrftoken'
axios.defaults.xsrfHeaderName = "X-CSRFTOKEN"

one important thing to mention here CORS is enabled by server, so I am not doing anything specific for that.

I also tried setting the cookie as natively by

document.cookie = "csrftoken=some token; Path=/; Expires=Mon, 16 Feb 2023 08:02:50 GMT;"; 

through this I can see the Cookie being set on browser but this still not sends the cookie with post request

As you can see I've also tried withCredentials: true which was one of the common proposed solutions by in my case this did not work as well.

About the Server config , the Django server is a standalone remote server and the same goes for Nuxt App as well.

I've been struggling with this for quite some time now, can anyone point out to me what can be the issue?

Upvotes: 7

Views: 13403

Answers (2)

Raghavendra N
Raghavendra N

Reputation: 3482

Copy pasting my answer from here:

Update (Nov, 2023):

According to the latest changes, there is a new property: withXSRFToken. You need to explicitly set it true to send the XSRF token.

From the pull request:

So now the user must explicitly set withXSRFToken to true to send XSRF token to third-party origins. By default withXSRFToken is undefined - the token will be sent only to the same origin.

Upvotes: 5

痛すぎる
痛すぎる

Reputation: 51

I had the same problem this is how I solved it

In order for axios to send the cookies withCredentials should be true, and while withCredentials is true the backend must send an Access-Control-Allow-Credentials header, else you'll get a cors missing allow credentials error and the cookies will not be set in the browser (the problem now is axios can't send the cookies since they were not even set in the browser to begin with).

You said you have CORS enabled so I assume you have corsheaders in your INSTALLED_APPS and you have added your vue front end url to the CORS_ALLOWED_ORIGINS list in settings.py. You should also add CORS_ALLOW_CREDENTIALS = True to settings.py.

Now in your vue app set the csrf cookie and header names like below this way you won't need to manually get the cookie value and set it to the X-CSRFToken header, axios will do that.

axios.defaults.xsrfCookieName = 'csrftoken'
axios.defaults.xsrfHeaderName = "X-CSRFToken"

then set withCredentials to true while making the request or you can set it as default like below

axios.defaults.withCredentials = true;

You can refer to this blog post

Upvotes: 5

Related Questions