So we have an random issue where every now and then the JWT token which we store in cookies for authentication is not set in the browser. Now 99% of the time a user goes to the login web page enter their details it sends a request to the server which sends back their user details and a JWT token set into the cookies. Now every now and then the cookie does not seem to be set. Its random has happened on nearly all browsers now but with no reason as to why. It happens in both our local, staging and production environments. (I have removed some code for privacy reasons)
The backend auth service is built using Node and ExpressJS it set the token with the following code:
module.exports.signIn = async function(req, res, next) {
try {
const { email, password } = req.body;
if (!email || !password)
throwBadRequest("Please enter a valid email and password");
const data = await Users.get(`?email=${email.toLowerCase().trim()}`);
const { name, val, options } = await Token.generateCookieParams(data);
res.cookie(name, val, options);
return res.json(toDTO(data));
} catch (err) {
next(err)
}
};
We are using the middleware cookie parser if that helps. Here is the code that set the token:
async function generateFor(user, expireTime, special = null) {
const payload = { id: user._id, type: user.type, account: user.account };
if (user.entity) {
payload.entity = user.entity;
}
if (special) {
payload.special = special;
}
const token = await jwt.sign(payload, config.secret, {
expiresIn: expireTime
});
return token;
}
async function generateCookieParams(user) {
const expireTime = 60 * 60 * 12; // 12 hour
const token = await Token.generateFor(user, expireTime);
return { name: config.tokenKey, val: token, options: { httpOnly: true } };
}
We are using the middleware cors for managing cors in the express app and have the option credentials set to true.
Then in the front end, we are using superagent to make all the request from the react app, we also used Axios as well but have the same issues. The base code for the networking looks like this in the front end:
import superagent from "superagent";
const superagentManager = {};
/**
* POST
* @param {string} path => the path for the post request
* @param {object} data => the object you are posting in json format
*/
superagentManager.post = async (path, data) => {
return await superagent
.post(path)
.withCredentials()
.type("application/json")
.send(data);
};
/**
* GET
* @param {string} path => the path for the get request
*/
superagentManager.get = async path => {
return await superagent
.get(path)
.withCredentials()
.type("application/json");
};
/**
* PATCH
* @param {string} path => the path for the patch request
* @param {object} data => the object you are posting in json format
*/
superagentManager.patch = async (path, data) => {
return await superagent
.patch(path)
.withCredentials()
.type("application/json")
.send(data);
};
/**
* DELETE
* @param {string} path => the path for the delete request
*/
superagentManager.delete = async path => {
return await superagent
.delete(path)
.withCredentials()
.type("application/json");
};
export default superagentManager;
If anyone could help me it would be much appreciated. The system works but every now and then let's say 1 out of every 50 logins it doesn't set the token in the browser. So the user object is returned from the login request but further request that happens straight afterwards throw an error as there is no token in the cookie. With the user base growing the bug is becoming more and more noticeable.