I have this function that I am using to protect my routes.
export function authUser(req, res, next) {
let token = req.cookies?.token;
if (token) {
jwt.verify(token, process.env.jwt_secret, (err, data) => {
if (err) {
res.sendStatus(403);
} else {
req.username = data;
next();
}
});
} else {
res.sendStatus(403);
}
}
This works completely fine
const authRoutes = express.Router();
authRoutes.get('/content', authUser, (req, res) => {
res.send(`This is the content in Content.vue for ${req.username}`);
});
app.use('/a', authRoutes);
But it would be annoying to add authUser to every route under authRoutes manually. I would like to do this so that every route in authRoutes goes through authUser
const authRoutes = express.Router();
authRoutes.use(authUser);
authRoutes.get('/content', (req, res) => {
res.send(`This is the content in Content.vue for ${req.username}`);
});
app.use('/a', authRoutes);
But the problem is when I do this, I get this error on the frontend
Cross-Origin Request Blocked: The Same Origin Policy disallows reading the remote resource at http://localhost:8182/a/content. (Reason: CORS preflight response did not succeed). Status code: 403.
I am puzzled on why the first approach works but the second doesn't. The issue is the fact that there are no cookies in req.cookies
when we get to authUser.
This is how cookies are set
let options = {
maxAge: 1000 * 60 * 0.25,
httpOnly: true, // Cookie will not be exposed to client side code
sameSite: 'none', // If client and server origins are different
secure: true, // use with HTTPS only
};
const token = jwt.sign(req.body.identifier, process.env.jwt_secret);
res.cookie('token', token, options);
res.sendStatus(200);
Aren't the two requests flowing the same way? Does authRoutes.use
send data back to the user before reaching a route?
The two setups are different: the first setup only applies the authUser
middleware to GET /a/content
, the second one applies it to every request made to /a/*
, including OPTIONS
requests used in CORS preflight requests.
And, as documented here, "a CORS-preflight request never includes credentials".