我是 JWT 和用于用户验证和登录的令牌的新手。我为 Node JS (NPM) 使用了以下扩展
var jwt = require('jsonwebtoken');
const cookieParser = require('cookie-parser')
require('dotenv').config();
// Express ..
我已经有一个登录名,可以检查 MongoDB(Node JS 作为服务器)用户,检查电子邮件和密码,然后使用访问令牌和刷新令牌设置 cookie。
我的登录代码就像
//create the access token with the shorter lifespan
let accessToken = jwt.sign(payload, process.env.ACCESS_TOKEN_SECRET, {
algorithm: "HS256",
expiresIn: process.env.ACCESS_TOKEN_LIFE
})
//create the refresh token with the longer lifespan
let refreshToken = jwt.sign(payload, process.env.REFRESH_TOKEN_SECRET, {
algorithm: "HS256",
expiresIn: process.env.REFRESH_TOKEN_LIFE
})
//send the access token to the client inside a cookie
res.cookie("_login", accessToken, {secure: true, httpOnly: true})
res.send()
这是刷新令牌发布的部分
exports.refresh = function (req, res, next){
console.log("Test");
let accessToken = req.cookies._login
if (!accessToken){
return res.status(403).send()
}
let payload
try{
payload = jwt.verify(accessToken, process.env.ACCESS_TOKEN_SECRET)
}
catch(e){
return res.status(401).send()
}
//retrieve the refresh token from the users array
let refreshToken = payload.email.refreshToken
//verify the refresh token
try{
jwt.verify(refreshToken, process.env.REFRESH_TOKEN_SECRET)
}
catch(e){
return res.status(401).send()
}
let newToken = jwt.sign(payload, process.env.ACCESS_TOKEN_SECRET,
{
algorithm: "HS256",
expiresIn: process.env.ACCESS_TOKEN_LIFE
})
res.cookie("_login", newToken, {secure: true, httpOnly: true})
res.send()
我现在的问题是,由于我在很多教程和指南中看到它们也通过 POST 使用刷新令牌,我如何与用户一起处理它?
客户端是否会发送 AJAX 或发布到中间件以检查访问令牌
-> 如果访问令牌已过期
--> 代码自动获取刷新令牌并发出新的访问令牌并给出确定?
或客户端发送到检查访问令牌的中间件
->访问令牌已过期(结果给用户)
->客户端现在将请求发布到 /refresh-token 结果= 新访问和刷新令牌
->再次使用新的 post 请求将请求发布到原始中间件?
这里的程序是什么,我找不到任何解决方法。
请记住,我的回答是基于我的经验。如果我碰巧在我的方式上犯了错误,请随时让任何人进行编辑。
因此,为了处理刷新令牌,我使用这种方式:
POST
请求的中间件。如果 JWT 已过期,请选择刷新令牌并调用您的/refresh-token-result
以获取新令牌。否则,只需不要对刷新令牌执行任何操作并继续您的请求。/refresh-token-result
接受请求令牌。端点将检查其有效性并返回一个新的访问令牌。哦,当用户注销时,确保您的用户的令牌和您的用户的刷新令牌都被正确撤销,通常是通过更改 cookie 值和expiresIn
属性。对我来说,我通常将两个 cookie 值都更改为loggedOut
并且将 设置expiresIn
为 5 秒。
或者,如果您使用的是 React(附加答案),您可以这样做:
useEffect()
钩子来更新您的访问令牌。TL;DR:你的第二种方法已经很好了。
编辑:示例伪代码来帮助你。不要立即复制粘贴,它很可能不起作用,但它应该让您大致了解事情是如何工作的。
// middleware.js
const { token, refreshToken } = req.cookies;
// 1. If the token has not expired, call 'next()'
// assume 'isExpired' returns boolean: true or false depending on the state of your token.
if (!token.isExpired()) {
return next();
}
// 2. If the token has expired AND the refreshToken has not expired, issue a new token, THEN call 'next()'
if (token.isExpired() && !refreshToken.isExpired()) {
await issueToken();
return next();
}
// 3. Else, logout the user. I'll keep this one short.
await logoutUser();
res.status(401).json({
status: 'fail',
message: 'Your access has expired! Please log in again!',
});
这是你的控制器。
// controller.js
const getAllComments = async (req, res, next) => {
const comments = await Comment.find();
res.status(200).json({
status: 'success',
data: comments,
});
}
而且,这就是您的路线应该是什么样子。
// this import might be unresolved - keep in mind!
const middleware = require('./middleware');
const getAllComments = require('./controllers');
router.get('/api/v1/comments/', middleware,
checkToken, getAllComments); // assume checkToken is your function to check for a token's validity.
请记住,我没有包含错误处理以保持此示例简短。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句