您的位置:

Jwt Refresh Token 的完整指南

一、什么是Jwt Refresh Token

Json Web Token(JWT)是一种在网络间传输信息的方式,常用于身份验证和授权。使用JWT需要在客户端使用密钥对数据进行签名,然后将令牌发回服务器以进行验证。但是,如果需要长时间访问某些内容,许多身份验证和授权令牌将过期。JWT Refresh Token允许客户端在过期的JWT之前提供一个新的JWT令牌。

JWT Refresh Token是一种标准的身份验证令牌,它允许客户端在过期之前自动重新生成新的令牌,而不需要进行用户重新登录或者授权。

二、Jwt Refresh Token 的工作原理

JWT是一种声明式的身份验证/授权机制,它由三部分组成:头部、载荷和签名。第一部分是头部,用于指定JWT类型和使用的签名算法。第二部分是载荷,包含有关用户的信息和其他元数据。第三部分是签名,用于验证JWT的完整性。这三个部分都是使用Base64进行编码的。

现在,假设在JWT令牌中有一个称为设置Refresh Token的字段,值为true。当该令牌在过期之前发现时,可以使用令牌中包含的“Refresh Token”生成新的JWT令牌并发送给客户端。

以下是JWT和Refresh Token工作的简要流程:

1.使用服务器端密钥和其他信息为JWT生成令牌。

2.返回JWT令牌和Refresh Token

3.客户端记录令牌和Refresh Token,并在每个之间进行快速切换。

4.当JWT令牌过期时,客户端使用Refresh Token请求新的JWT令牌。

5.刷新新的JWT令牌并继续使用。

三、Jwt Refresh Token 的优势

使用JWT Refresh Token有几个优点:

1.颁发长期有效的访问令牌。使用Refresh Token可以将访问令牌的有效期延长到较长的时间。

2.降低服务器负载。使用Refresh Token可以减少对服务器的访问,因为客户端可以在一段时间内自行处理验证和更新令牌。

3.提高安全性。使用Refresh Token可以减少发生中间人攻击的机会,因为JWT令牌有效期非常短,而Refresh Token有效期长。

四、如何实现Jwt Refresh Token

实现JWT Refresh Token需要进行以下步骤:

1.创建初始JWT令牌

const jwt = require('jsonwebtoken');
const jwtKey = 'your_jwt_secret';//jwt密钥
const jwtExpirySeconds = 300; //JWT Token的有效期为5分钟

const userName = 'your_username';//用户名称

const token = jwt.sign({ userName }, jwtKey, {
  algorithm: 'HS256',
  expiresIn: jwtExpirySeconds
});

2.生成Refresh Token

为每个JWT令牌生成一个Refresh Token,用于在令牌到期之前获取新的令牌。

const RefreshToken = require('../models/refresh-token.model');//引入 RefreshToken 模型

const generateRefreshToken = async (userName) => {
  const refreshToken = new RefreshToken({
    userName: userName,
    token: crypto.randomBytes(40).toString('hex'), //生成一个40位的随机Refresh Token
    expires: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000) //Refresh Token有效期7天
  });
  await refreshToken.save();
  return refreshToken;
}

3.验证JWT令牌并生成新的JWT令牌

const verify = require('./verify');//引入 JWT 验证方法

const refreshToken = async (oldToken) => {
  const oldDecodedToken = jwt.decode(oldToken);
  const refreshToken = await RefreshToken.findOne({ userName: oldDecodedToken.userName });
  if (!refreshToken) return;//传递的旧Token的refreshToken不存在

  //验证RefreshToken是否过期
  if (refreshToken.expires.valueOf() < Date.now()) {
    await refreshToken.remove();//删除RefreshToken
    return;//refreshToken已过期
  }

  //验证JWT令牌的签名,以确保它没有被改变
  const { algorithm } = jwt.decode(oldToken, { complete: true }).header;
  await verify(oldToken, jwtKey, algorithm);

  const newToken = jwt.sign({ userName: oldDecodedToken.userName }, jwtKey, {
    algorithm: algorithm,//使用相同的算法
    expiresIn: jwtExpirySeconds
  });
  return newToken;
}

4.使用Refresh Token获取新的JWT令牌

const express = require('express');

const router = express.Router();
const RefreshToken = require('../models/refresh-token.model');
const jwtRefreshToken = require('../middleware/jwt-refreshtoken.middleware');
const jwt = require('jsonwebtoken');
const jwtKey = 'your_jwt_secret';//jwt密钥

router.post('/', jwtRefreshToken, async (req, res) => {
  try {
    const oldToken = req.token;//传递的旧的JWT令牌
    const newToken = await refreshToken(oldToken);//生成新的JWT令牌
    if (!newToken) {
      res.status(401).send("Unauthorized");//新的JWT令牌被拒绝
      return;
    }
    res.json({ token: newToken });//发送新的JWT令牌
  } catch (err) {
    res.status(500).send(err);//服务器错误
  }
});

module.exports = router;

五、总结

Jwt Refresh Token 是一种长期有效的身份验证令牌,可以提高客户端的使用体验,降低服务器负载和提高安全性。实现 JWT Refresh Token 具有重要的意义,需要根据具体的业务需求进行定制化开发。