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

后端部分

安装

npm install jsonwebtoken
npm install express-jwt

使用

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

})

前端部分

新建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

新建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传给后端
    })
  },
  
  ...

}

路由守卫

//路由守卫
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()
  }

})

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

在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_54218079/article/details/128066525
今日推荐