【发布时间】:2022-10-24 16:56:30
【问题描述】:
拜托,我正在做一个节点具有注册和登录功能的 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 过期了。
-
cookie 不能过期,它设置为一天。
-
在开发工具中打开网络选项卡并检查请求和响应。必须有一个包含 cookie 的最后一个请求和一个没有 cookie 的第一个请求。在那里您应该找到修改或删除 cookie 的响应。
-
不得不提的是,我是用迅雷客户端来测试API的,当我查看cookies选项卡时,它显示“No Cookies Available”
-
刷新令牌不属于 cookie!为什么还要在这一点上使用单独的刷新/访问令牌? evertpot.com/jwt-is-a-bad-default 。为什么不是 OAuth2?不要自己滚动
标签: javascript node.js rest authentication jwt