Reputation: 973
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
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