vue3+node.js实现无感刷新token

本文介绍了如何在Web应用中使用jsonwebtoken库生成和验证access和refreshtoken,包括后端生成token、axios请求拦截器、token验证、无感刷新机制以及刷新令牌的时效性检查。
摘要由CSDN通过智能技术生成

首先需要下载 jsonwebtoken包,用于在后端生成token,校验token 

1.用户点击登录,在后端生成两个token,传给客户端进行保存。

//手机号登录
var access = "accessToken"
var refresh = "refreshToken"
router.post("/phoneLogin",async (req,res)=>{
    var {phone} = req.body
    var data = await LoginModel.find({phone:phone})
    if(data.length > 0){
        var accessToken = jwt.sign({ phone:phone }, access, { expiresIn: '10s' });
        var refreshToken = jwt.sign({ phone:phone }, refresh, { expiresIn: '10h' });
        res.send({
            code:200,
            accessToken:accessToken,
            refreshToken:refreshToken,
            msg:"登录成功"
        })
    }else{
      res.send({
          code:500,
          msg:"账号不存在"
      })
    }
})

2.封装axios请求拦截器,将token添加到请求头中,以验证token的有效性。

// 创建一个axios实例
const instance = axios.create({
    baseURL: 'http://localhost:3000',
  })



// 请求拦截器
instance.interceptors.request.use(
  (config) => {
    // 从本地存储或 Cookie 中获取 access token
    const accessToken = localStorage.getItem('accessToken')
    // 将 access token 添加到请求头中
    if (accessToken) {
        config.headers['Authorization'] = `Bearer ${accessToken}`;
    }
    return config;
  },
  (error) => {
    return Promise.reject(error);
  }
);

3.后端验证token的时效性,并应用。

const jwt = require("jsonwebtoken")

var access = "accessToken"
const verifyAccessToken = (req, res, next) => {
    const token = req.headers.authorization?.split(' ')[1];
    if (!token) {
      return res.status(403).json({ message: 'Unauthorized' });
    }
    jwt.verify(token, access, (err, user) => {
      if (err) {
        return res.status(403).json({ message: 'Invalid token' });
      }
      req.user = user;
      next();
    });
  }

  module.exports = { verifyAccessToken }




//测试无感刷新
const {verifyAccessToken} = require("../jwt/jwt")

router.get("/aaa",verifyAccessToken,async (req,res)=>{
  res.send({
    msg:"成功喽!"
  })
})

4.前端封装响应拦截器,如果token失效了就发送刷新token的请求。

//响应拦截器
instance.interceptors.response.use(
   (response) => {
    //成功的响应
    console.log(response.data);
    return response;
  },
   async(error) => {
    //失败的响应
    console.log(error.response.status);
    if(error.response.status == 401){
      showToast('还未登录,请登录!');
      return false
    }
    if (error.response.status === 403) {
      // 尝试刷新 Token
      try {
        const {data:{newAccessToken,newrefreshToken}} = await instance.post('/lkx/refreshtoken', {
          refreshToken: localStorage.getItem('refreshToken'),
        });
        localStorage.setItem('accessToken', newAccessToken);
        localStorage.setItem('refreshToken',newrefreshToken)
        console.log("token刷新啦!");
        // 重新发送原始请求
        return instance(error.response.config);
      } catch (err) {
        // 刷新 Token 失败,跳转到登录页
        // 你可以根据具体情况执行其他操作
        // 清除 Token
        localStorage.removeItem('accessToken');
        localStorage.removeItem('refreshToken');
        // 跳转到登录页
        // window.location.href = '/login';
        return Promise.reject(err);
      }
    }
    return Promise.reject(error);
  }
);

5.后端判断刷新令牌的时效性,如果刷新令牌失效了就返回错误响应,如果没有失效,就刷新token。

//刷新令牌
router.post("/refreshtoken",async(req,res)=>{
  const refreshToken = req.body.refreshToken;
  if (!refreshToken) {
    return res.status(401).json({ message: 'Invalid refresh token' });
  }
  jwt.verify(refreshToken, refresh, (err, user) => {
    if (err) {
      return res.status(401).json({ message: 'Invalid refresh token' });
    }
    // 生成新的 Access Token
    const newAccessToken = jwt.sign({phone:user.phone}, access, { expiresIn: '10s' });
    const newrefreshToken = jwt.sign({ phone:user.phone }, refresh, { expiresIn: '10h' });
    res.send({ newAccessToken,newrefreshToken });
  });
})

 ok啦!!!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值