• vue+nodejs+express+jwt如何生成并处理token


    后端部分

    安装

    npm install jsonwebtoken
    npm install express-jwt
    
    • 1
    • 2

    使用

    const jwt = require('jsonwebtoken') // 生成 JWT 字符串
    const { expressjwt } = require('express-jwt')// 将客户端发送来的 JWT 字符串解析成 JSON
    const app = express()
    
    const secret = 'forexample' // 密钥用于加密
    const expiresIn = { expiresIn: "15 days" } // 设置token过期时间
    const whiteList = ['/login', '/register'] // 白名单,没有token也放行
    
    // 生成token
    // info是payload是需要存入token的信息
    function createToken (info) {
      let token = jwt.sign(
        info, secret, expiresIn)
      return token
    }
    
    // 校验token
    app.use(expressjwt({
      secret: secret,
      algorithms: ['HS256'], // 加密算法,HS256是默认值
      // 设置为true表示校验,false表示不校验,默认值为true
      // credentialsRequired: true,
    }).unless({ path: whiteList })) // 对白名单里的路径直接放行
    
    // 拦截器
    app.use((err, req, res, next) => {
      // 如果错误是由 token 解析失败导致的
      if (err.name === 'UnauthorizedError') {
        return res.send({
          status: 401,
          message: '无效的token'
        })
      }
      res.send({
        status: 500,
        message: '未知的错误'
      })
    })
    
    /**
     * 实现登录验证功能
     */
    app.post('/login', function (req, res) {
              ......
              
            // 生成 JWT 字符串,根据需要传入参数,注意别将用户密码加密到 Token 中
            let token = createToken({ userid: rows[0].userid })
            // 将token传给前端
            res.send({ status: 200, message: '登录成功!', token: token })
    
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    前端部分

    新建axios.js

    在这里插入图片描述

    import axios from "axios"
    import router from "../router"
    import { Message, Loading } from "element-ui"
    
    const service = axios.create({
      // baseURL: _baseURL,
      timeout: 600000,
      withCredentials: true,
      headers: {
        'Content-Type': 'application/x-www-form-urlencoded;charset=utf-8'
      }
    })
    
    ......
    
    // axios 请求处理超时处理
    service.interceptors.response.use(
      function (response) {
        if (response.data.status == 401) {
          // token过期,需要登录
          console.log("token过期")
          Message({
            message: "token已过期,请重新登录",
            type: "warning",
          })
          localStorage.removeItem("token") 
          router.push("/").catch(err => {}) // catch解决路由重复点击报错
          return false
        }
        return response
      },
      (err) => {
        if (err.message === "Network Error") {
          Message.error("网络异常,请检查网络连接情况")
        }
        return Promise.reject(err.response.data)
      }
    )
    export default service
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39

    新建index.js

    在这里插入图片描述

    import axios from './axios' // 上面的axios.js
    import qs from "qs" // axios默认请求头是application/x-www-form-urlencoded,qs用于提交表单
    
    export default {
      
      ...
      
      getTop10: () => {
        return axios.get('/api/getTop10', {
          headers: { Authorization: "Bearer " + localStorage.getItem("token") }, // 将token传给后端
        })
      },
      
      ...
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    路由守卫

    //路由守卫
    router.beforeEach((to, from, next) => {
      // console.log("to", to)
      // 目标路由不是登录页,并且还需要token验证,还没有token,那就直接给返回到登录页
      if (to.name !== 'login' && to.meta.authRequired && !localStorage.getItem('token')) {
        Message({
          message: "请先登录",
          type: "warning",
        })
        next({ name: 'login' })
      } else {
        // 放行
        next()
      }
    
    })
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    to.meta.authRequired是写router时自己设定的

    在这里插入图片描述

  • 相关阅读:
    【前缀“选区-” bat脚本】
    JavaScript 判断客户端是手机还是pad
    【花书笔记】 之 Chapter01 引言
    python安装第三方包的几种方式
    基于Springcloud搭建电商平台实现高性能高并发微服务
    I/O多路转接
    大三第十一周学习笔记
    明日方舟游戏助手:一键完成日常任务 | 开源日报 No.233
    2 Spring Boot 整合 Thymeleaf
    怎样恢复误删和损坏磁盘上的文件
  • 原文地址:https://blog.csdn.net/weixin_54218079/article/details/128066525