I am sending requests from the client to my Express.js server using Axios.
I set a cookie on the client and I want to read that cookie from all Axios requests without adding them manually to request by hand.
This is my clientside request example:
axios.get(`some api url`).then(response => ...
I tried to access headers or cookies by using these properties in my Express.js server:
req.headers
req.cookies
Neither of them contained any cookies. I am using cookie parser middleware:
app.use(cookieParser())
How do I make Axios send cookies in requests automatically?
Edit:
I set cookie on the client like this:
import cookieClient from 'react-cookie'
...
let cookie = cookieClient.load('cookie-name')
if(cookie === undefined){
axios.get('path/to/my/cookie/api').then(response => {
if(response.status == 200){
cookieClient.save('cookie-name', response.data, {path:'/'})
}
})
}
...
While it's also using Axios, it is not relevant to the question. I simply want to embed cookies into all my requests once a cookie is set.
You can use withCredentials
property.
XMLHttpRequest from a different domain cannot set cookie values for their own domain unless withCredentials is set to true before making the request.
axios.get(BASE_URL + '/todos', { withCredentials: true });
Also its possible to force credentials to every Axios requests
axios.defaults.withCredentials = true
Or using credentials for some of the Axios requests as the following code
const instance = axios.create({
withCredentials: true,
baseURL: BASE_URL
})
instance.get('/todos')
TL;DR:
{ withCredentials: true }
or axios.defaults.withCredentials = true
From the axios documentation
withCredentials: false, // default
withCredentials
indicates whether or not cross-site Access-Control requests should be made using credentials
If you pass { withCredentials: true }
with your request it should work.
A better way would be setting withCredentials
as true
in axios.defaults
axios.defaults.withCredentials = true
It's also important to set the necessary headers in the express response. These are those which worked for me:
app.use(function(req, res, next) {
res.header('Access-Control-Allow-Origin', yourExactHostname);
res.header('Access-Control-Allow-Credentials', true);
res.header('Access-Control-Allow-Headers', 'Origin, X-Requested-With, Content-Type, Accept');
next();
});
X-PINGOTHER
into Access-Control-Allow-Headers
has been mandatory for me (Node.js 6.9 with Express 4.16, Chrome 63). Check JakeElder's post on this GitHub issue: github.com/axios/axios/issues/191#issuecomment-311069164
axios.defaults.withCredentials = true;
on my frontend axios config. Once removing the create-react-app proxy in package.json, we needed to enable withCredentials, as well as include the above middleware in our express app. Thank you
I am not familiar with Axios, but as far as I know in javascript and ajax there is an option
withCredentials: true
This will automatically send the cookie to the client-side. As an example, this scenario is also generated with passportjs, which sets a cookie on the server
So I had this exact same issue and lost about 6 hours of my life searching, I had the
withCredentials: true
But the browser still didn't save the cookie until for some weird reason I had the idea to shuffle the configuration setting:
Axios.post(GlobalVariables.API_URL + 'api/login', {
email,
password,
honeyPot
}, {
withCredentials: true,
headers: {'Access-Control-Allow-Origin': '*', 'Content-Type': 'application/json'
}});
Seems like you should always send the 'withCredentials' Key first.
URL
, {data}, {withCredentials: true}). while your GET allows for the withCredentials to be sent with the data: axios.get(URL
, {data, withCredentials: true}). At least for me in my react -> express operations.
You can use withCredentials
property to pass cookies in the request.
axios.get(`api_url`, { withCredentials: true })
By setting { withCredentials: true }
you may encounter cross origin issue. To solve that you need to use
expressApp.use(cors({ credentials: true, origin: "http://localhost:8080" }));
Here you can read about withCredentials
What worked for me:
Client Side:
import axios from 'axios';
const url = 'http://127.0.0.1:5000/api/v1';
export default {
login(credentials) {
return axios
.post(`${url}/users/login/`, credentials, {
withCredentials: true,
credentials: 'include',
})
.then((response) => response.data);
},
};
Note: Credentials will be the body of the post request, in this case the user login information (Normally obtained from the login form):
{
"email": "user@email.com",
"password": "userpassword"
}
Server Side:
const express = require('express');
const cors = require('cors');
const app = express();
const port = process.env.PORT || 5000;
app.use(
cors({
origin: [`http://localhost:${port}`, `https://localhost:${port}`],
credentials: 'true',
})
);
credentials
argument of login
function?
How do I make Axios send cookies in requests automatically?
set axios.defaults.withCredentials = true;
or for some specific request you can use axios.get(url,{withCredentials:true})
this will give CORS error if your 'Access-Control-Allow-Origin' is set to wildcard(*). Therefore make sure to specify the url of origin of your request
for ex: if your front-end which makes the request runs on localhost:3000 , then set the response header as
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:3000');
also set
res.setHeader('Access-Control-Allow-Credentials',true);
Fatih's answer is still valid and great in 2021.
Also axios.defaults.withCredentials = true
will do the trick.
It seems passing { withCredentials: true }
to individual axios calls is deprecated.
for people still not able to solve it, this answer helped me. stackoverflow answer: 34558264
TLDR; one needs to set {withCredentials: true}
in both GET request as well the POST request (getting the cookie) for both axios as well as fetch.
{ withCredentials: true }
in GET request did not have any effect.
withCredentials: true
to the request config but not this detail. I spent almost 2 days trying to solve the problem until I came across this
Another solution is to use this library:
https://github.com/3846masa/axios-cookiejar-support
which integrates "Tough Cookie" support in to Axios. Note that this approach still requires the withCredentials
flag.
You are getting the two thinks mixed.
You have "react-cookie" and "axios"
react-cookie => is for handling the cookie on the client side
axios => is for sending ajax requests to the server
With that info, if you want the cookies from the client side to be communicated in the backend side as well, you will need to connect them together.
Note from "react-cookie" Readme:
Isomorphic cookies! To be able to access user cookies while doing server-rendering, you can use plugToRequest or setRawCookie.
If this is what you need, great.
If not, please comment so I could elaborate more.
plugToRequest
exactly do? I thought to access cookies on the node server, all one needs is the cookie-parser
middleware (assuming Express)?
This worked for me:
First, I had to make a new instance of axios with a custom config
Then, I used that axios instance to make a post request
See code below:
const ax = axios.create({
baseURL: 'yourbaseUrl',
withCredentials: true,
});
const loginUser = () => { const body ={username:state.values.email, password:state.values.password};
ax.post('/login',body).then(function(response){
return response}).then().catch(error => console.log(error));}
source: https://www.npmjs.com/package/axios#creating-an-instance
For anyone where none of these solutions are working, make sure that your request origin equals your request target, see this github issue.
I short, if you visit your website on 127.0.0.1:8000, then make sure that the requests you send are targeting your server on 127.0.0.1:8001 and not localhost:8001, although it might be the same target theoretically.
Success story sharing
Access-Control-Allow-Origin
in response header isn't set to wildcard (*)Access-Control-Allow-Origin
isn't set to*
it means, I won't make request to that server because of CORS rightAccess-Control-Allow-Origin
's value to the domain you want to make XHR request from. e.g.https://a.com
is the server,https://b.com
is the client, andhttps://b.com
is loaded in someone's browser and is usingXMLHTTPRequest
to make request tohttps://a.com
. In addition forXMLHTTPRequest
(initiated inhttps://a.com
) to setwithCredential: true
, the server -https://b.com
also needs to be configured so the response header containsAccess-Control-Allow-Origin: https://a.com
https://b.com
in your example represents the client, so thereforeXMLHTTPRequest
should be initiated inb
instead ofa
?withCredentials: true
to the call receiving the cookie. Otherwise the next calls you do won't use the retrieved cookie