node.js - 刷新 token 如何处理 POST 路由

标签 node.js jwt

我对用于用户验证和登录的 JWT 和 token 不熟悉。我对 Node JS (NPM) 使用了以下扩展

var jwt = require('jsonwebtoken');
const cookieParser = require('cookie-parser')
require('dotenv').config();
// Express ..

我已经有一个登录名,可以检查 MongoDB(Node JS 作为服务器)用户,检查电子邮件和密码,然后使用访问 token 和刷新 token 设置 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()

这是刷新 token 发布的部分

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 使用刷新 token ,所以我如何与用户一起处理它?<​​/p>

客户端是否会发送 AJAX 或发布到中间件以检查访问 token

-> 如果访问 token 已过期

--> 代码自动获取刷新 token 并发出新的访问 token 并给出“确定”?

客户端发送到检查访问 token 的中间件

-> 访问 token 已过期(结果给用户)

-> 客户端现在向/refresh-token 结果发布请求 = 新的访问和刷新 token

-> 再次将请求发送到原始中间件并使用新的发布请求?

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

最佳答案

请记住,我的回答是基于我的经验。如果我的方法碰巧犯了错误,请随时进行编辑。

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

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

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

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

  • 如果用户访问您的网站,并且 JWT 到期日期即将到期,您只需使用 useEffect() Hook 即可更新您的访问 token 。

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 。

// 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.

请记住,为了简短起见,我没有包含错误处理。

关于node.js - 刷新 token 如何处理 POST 路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66614039/

相关文章:

jwt - postman 收集授权不存在于文档标题中

spring - 响应中不存在刷新 token

javascript - 浏览器关闭时注销

javascript - 使用神经网络预测下一个结果

node.js - Mongoose:嵌套数组结构中的聚合查询

javascript - 一次等待一个查询

node.js - 使用express-jwt 仅保护部分路由

javascript - 如何对 TypeScript 类执行 Joi 验证?

javascript - 使用 NodeJS 按属性排序嵌套的 JSON

php - 在 jwt-auth laravel 中获取自定义声明