刷新过期的JWT令牌

时间:2019-05-15 08:30:23

标签: jwt

这是我在后端的中间件

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);代码保存在本地存储中。

1 个答案:

答案 0 :(得分:0)

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

  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");
});