刷新令牌如何处理POST路由

开发者

我是 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 请求将请求发布到原始中间件

这里的程序是什么,我找不到任何解决方法。

尼古拉斯·D

请记住,我的回答是基于我的经验。如果我碰巧在我的方式上犯了错误,请随时让任何人进行编辑。

因此,为了处理刷新令牌,我使用这种方式:

  • 当用户成功登录时,JWT(包含用户的身份验证)和刷新令牌(包含用户的刷新令牌)将放置在用户的 cookie 中(与您相同)。
  • 用户将在您的 Web 应用程序中做他/她的事情,直到他/她关闭浏览器而不退出。
  • 请记住,JWT 总是有到期日期——我们会记住这个到期日期。
  • 在每个请求中,您都会将特定的 JWT(包含用户的身份验证)和刷新令牌发送到您要发出POST请求的中间件如果 JWT 已过期,请选择刷新令牌并调用您的/refresh-token-result以获取新令牌。否则,只需不要对刷新令牌执行任何操作并继续您的请求。
  • 确保您/refresh-token-result接受请求令牌。端点将检查其有效性并返回一个新的访问令牌。
  • 如果刷新令牌已过期,请注销用户。这是出于安全原因,这很重要!

哦,当用户注销时,确保您的用户的令牌和您的用户的刷新令牌都被正确撤销,通常是通过更改 cookie 值和expiresIn属性。对我来说,我通常将两个 cookie 值都更改为loggedOut并且将 设置expiresIn为 5 秒。

或者,如果您使用的是 React(附加答案),您可以这样做:

  • 如果用户访问您的网站,并且 JWT 到期日期即将到期,您可以简单地使用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] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章