Reputation: 1907
I have a nodejs/express + React CRA application, and I'm trying to set a cookie from nodejs. The server is on port 4001, so in my React application's project.json I have "proxy": "http://localhost:4001"
set, but the cookie still won't get set in the browser.
I've tested it in production mode as well, with the React application being served from nodejs directly and it all works fine there.
Here is how I am setting the cookie. I've tried several different combinations of options here and they all have the same result.
res.cookie('jwt', token, {
httpOnly: false,
sameSite: false,
signed: false,
secure: false,
encode: String
});
res.header('Access-Control-Allow-Credentials', 'true');
Edit: On the client side I am using Axios for my ajax requests.
Edit:
Here is the endpoint function for login (POST /api/users/login):
login: function(req, res) {
User.findOne({
$or: [{email: req.body.username}, {username: req.body.username}]
}).exec().then(user => {
if(user) {
if(user.checkPassword(req.body.password)) {
jwt.sign({ userID: user._id }, 'secret', (err, token) => {
res.cookie('jwt', token, {
httpOnly: false,
sameSite: false,
signed: false,
secure: false,
encode: String
});
res.header('Access-Control-Allow-Credentials', 'true');
res.status(200).send({ status: 'ok', message: 'Success'});
});
}
else {
return res.status(401).send({ status: 'error', message: 'Invalid username/password combination. Please try again.' });
}
}
else {
return res.status(401).send({ status: 'error', message: 'Invalid username/password combination. Please try again.' });
}
}, err => {
return res.status(500).send({ status: 'error', message: 'unexpected error' });
});
}
Here is the client-side login code:
login(username, password) {
return new Promise((resolve, reject) => {
axios({
method: 'post',
url: 'http://localhost:4001/api/users/login',
data: {
username,
password
}
}).then((res) => {
resolve(res.data);
}, (err) => {
reject(err);
});
});
}
Server is on port 4001, React CRA server is on 3000
Upvotes: 16
Views: 6701
Reputation: 955
According to what riwu mentioned cookie domain should match, in my case setting "cookieDomainRewrite": "localhost",
works
Below complete config for setupProxy.js
in React:
const {createProxyMiddleware} = require('http-proxy-middleware');
module.exports = function (app) {
app.use(
'/api',
createProxyMiddleware({
target: 'http://localhost:8000',
changeOrigin: true,
cookieDomainRewrite: "localhost",
})
);
};
Upvotes: 0
Reputation: 11270
To allow the browser to set cookies and adhere to Same Origin Policy, your client code should query http://localhost:3000/api/users/login
(same host as client) instead of the (proxied) server url (port 4001).
You can also specify the base url as ${window.location.origin}/api
or just /api
.
Upvotes: 10