是否有办法知道为什么cookie没有被发送到服务器



请,我正在工作在一个Nodejs带有注册和登录功能的REST api,

  • 当用户登录时,他们获得一个accessToken。
  • 其次,保存一个包含refreshToken的cookie,使用户能够向/refresh端点请求新的accessToken。

这是我的问题;当用户登录时,我可以看到cookie,但在后续向其他路由请求后,cookie消失并且不再发送到服务器,从而阻止我向/refresh端点请求新的accessToken。

// log-in controller
const User = require('../model/User');
const bcrypt = require('bcrypt');
const jwt = require('jsonwebtoken');
const handleLogin = async (req, res) => {
const { user, pwd } = req.body;
if (!user || !pwd) return res.status(400).json({ 'message': 'Username and password are required.' });
const foundUser = await User.findOne({ username: user }).exec();
if (!foundUser) return res.sendStatus(401); //Unauthorized 
// evaluate password 
const match = await bcrypt.compare(pwd, foundUser.password);
if (match) {
const roles = Object.values(foundUser.roles).filter(Boolean);
// create JWTs
const accessToken = jwt.sign(
{
"UserInfo": {
"username": foundUser.username,
"roles": roles
}
},
process.env.ACCESS_TOKEN_SECRET,
{ expiresIn: '10s' }
);
const refreshToken = jwt.sign(
{ "username": foundUser.username },
process.env.REFRESH_TOKEN_SECRET,
{ expiresIn: '1d' }
);
// Saving refreshToken with current user
foundUser.refreshToken = refreshToken;
const result = await foundUser.save();
console.log(result);
console.log(roles);
// Creates Secure Cookie with refresh token
res.cookie('jwt', refreshToken, { httpOnly: true, secure: true, sameSite: 'None', maxAge: 24 * 60 * 60 * 1000 });
// Send authorization roles and access token to user
res.json({ roles, accessToken });
} else {
res.sendStatus(401);
}
}
module.exports = { handleLogin };


// refresh endpoint controller
const User = require('../model/User');
const jwt = require('jsonwebtoken');
const handleRefreshToken = async (req, res) => {
const cookies = req.cookies;
if (!cookies?.jwt) return res.sendStatus(401);
const refreshToken = cookies.jwt;
const foundUser = await User.findOne({ refreshToken }).exec();
if (!foundUser) return res.sendStatus(403); //Forbidden 
// evaluate jwt 
jwt.verify(
refreshToken,
process.env.REFRESH_TOKEN_SECRET,
(err, decoded) => {
if (err || foundUser.username !== decoded.username) return res.sendStatus(403);
const roles = Object.values(foundUser.roles);
const accessToken = jwt.sign(
{
"UserInfo": {
"username": decoded.username,
"roles": roles
}
},
process.env.ACCESS_TOKEN_SECRET,
{ expiresIn: '10s' }
);
res.json({ roles, accessToken })
}
);
}
module.exports = { handleRefreshToken }

我遇到了与您相同的问题:客户端无法在子顺序请求中发送cookie。我在handleLogin中更改res.cookie后修复了这个问题。试试吧:

res.cookie('jwt', refreshToken, { httpOnly: true, maxAge: 24 * 60 * 60 * 1000 });

请检查您是否在server.js的正确位置使用cookie解析器中间件

JWT刷新令牌是一次性的。因此,在用户在JWT服务器上登录后的代码中,您将获得在10秒内到期的accessToken,以及保存到用户浏览器cookie中的刷新令牌。在accessToken过期后,您将使用用户的refreshToken生成新的accessToken。此时,您当前的refreshToken已经过期,当您尝试再生成一个accessToken(在10秒内)时,它将失败。因此,在handleRefreshToken()函数中,您需要生成全新的refreshToken:

const refreshToken = jwt.sign(
{ "username": foundUser.username },
process.env.REFRESH_TOKEN_SECRET,
{ expiresIn: '1d' }
);
// Saving refreshToken with current user
foundUser.refreshToken = refreshToken;
const result = await foundUser.save();
console.log(result);
console.log(roles);
// Creates Secure Cookie with refresh token
res.cookie('jwt', refreshToken, { httpOnly: true, secure: true, sameSite: 'None', maxAge: 24 * 60 * 60 * 1000 });

最新更新