【问题标题】:Refresh expired JWT token刷新过期的 JWT 令牌
【发布时间】:2019-05-15 19:44:55
【问题描述】:

这是我在后端的中间件

const jwt = require('jsonwebtoken');
const User = require('../models/user');

module.exports = (req, res, next) => {
const auth = req.get('Authorization');

if (!auth) {
    return res.status(401).json({
        "response": {
            "message": 'Not authorized user',
        }
    })
}

const token = auth.split(' ')[1];
let decode;
try {
    decode = jwt.verify(token, process.env.JWT_SECRET_KEY)
} catch (err) {
    return res.status(401).json({
        "response": {
            "message": 'Invalid token access',
        }
    })
}

if (!decode) {
    return res.status(500).json({
        "response": {
            "message": 'Error token access',
        }
    })
}

let userId = decode.id;

User.findById(userId)
    .then(user => {
        req.user = user;
        next();
    }).catch(err => {
        console.log(err);
        res.status(401).json({
            "response": {
                "message": `Error on authorization`,
            }
        })
    })
}

我需要在每次调用过期时集成自动刷新令牌,如何在客户端的本地存储中重新保存?

让我的前端使用 vue 和 vuex 开发。使用此 localStorage.setItem('access_token', token); 代码保存在本地存储中。

【问题讨论】:

    标签: jwt


    【解决方案1】:

    以下是我在自己的网络应用中所做的逻辑

    1. 当用户登录时,您需要创建访问和刷新令牌
    2. 收到两个令牌后,请将它们保存在 localStorage 或任何安全的地方
    3. 您需要创建一个 refreshToken 路由(/refresh-token),以便在访问令牌过期时调用
    4. 定义一个中间件来检查令牌并在安全路由中使用它
    5. 当您收到 401 错误时,调用 /refresh-token 路由来刷新令牌 配置文件
    {
      "secret": "secret",
      "refreshTokenSecret": "refresh-secret",
      "port": 8080,
      "tokenLife": 900,
      "refreshTokenLife": 86400
    }
    

    登录路径(app.js)

    router.get('/login',(req, res) => {
     const postData = req.body;
     const user = {
         "email": postData.email,
         "name": postData.name
     }
     const token = jwt.sign(user, config.secret, { expiresIn: config.tokenLife})
     const refreshToken = jwt.sign(user, config.refreshTokenSecret, { expiresIn: 
     config.refreshTokenLife})
     const response = {
       "status": "Logged in",
       "token": token,
       "refreshToken": refreshToken,
     }
     tokenList[refreshToken] = response
     res.status(200).json(response);
    }
    

    刷新令牌路由(app.js)

    router.post('/refresh-token', (req,res) => {
        const postData = req.body
        if((postData.refreshToken) && (postData.refreshToken in tokenList)) {
            const user = {
                "email": postData.email,
                "name": postData.name
            }
            const token = jwt.sign(user, config.secret, { expiresIn: config.tokenLife})
            const response = {
                "token": token,
            }
            // update the token in the list
            tokenList[postData.refreshToken].token = token
            res.status(200).json(response);        
        } else {
            res.status(404).send('Invalid request')
        }
    })
    
    

    tokenMiddleware.js

    const jwt = require('jsonwebtoken')
    const config = require('./config')
    
    module.exports = (req,res,next) => {
      const token = req.body.token || req.query.token || req.headers['x-access-token']
      if (token) {
        jwt.verify(token, config.secret, function(err, decoded) {
            if (err) {
                return res.status(401).json({"error": true, "message": 'Unauthorized access.' });
            }
          req.decoded = decoded;
          next();
        });
      } else {
        return res.status(403).send({
            "error": true,
            "message": 'No token provided.'
        });
      }
    }
    
    

    使用中间件保护路由

    router.get('/secured-route', tokenMiddleware, async (req, res) => {
        res.send("secured");
    });
    

    【讨论】:

    • 此文本当您收到 401 错误调用 /refresh-token 路由以刷新令牌时打算用于客户端?
    • 是的,当您使用访问令牌调用安全 api 并且它给您未经授权的错误时,您可以从客户端通过发送访问令牌和刷新令牌来刷新访问令牌以获取新的访问令牌并调用使用新的访问令牌再次保护 api
    • 如果你想用一个库来处理auth,代码更少,你可以看看passport.js library for express example
    • @onuriltan 我有两个问题:1.如何在调用刷新令牌端点后重新发送先前的请求? 2.如果一次有多个请求要发送到后端,那么如果token过期,所有请求都会失败,那么如何防止所有这些失败的请求都发送刷新token请求?
    猜你喜欢
    • 2019-07-04
    • 2018-07-22
    • 2018-08-05
    • 2019-02-11
    • 1970-01-01
    • 2019-09-28
    • 1970-01-01
    • 2016-03-05
    • 2016-06-25
    相关资源
    最近更新 更多