前言
   
做过前后端分离项目的同学应该都做过 token 验证,在前端登录的时候需要缓存后端传过来的 token,然后在需要验证权限的接口带上 token。本章节来实现使用 node 进行 token 的权限验证。
    
    
    技术准备
   
    
     1、express
    
   
    应用中使用了 express 框架,安装过程可查看
    
    
     https://blog.csdn.net/weixin_43930421/article/details/125926741
    
   
    
     2、安装 jsonwebtoken 和 express-jwt
    
   
npm install jsonwebtoken express-jwt
jsonwebtoken 用来转换用户 json 信息为 token 串,express-jwt 则用来解析 json 进行验证。
    
     3、MySQL
    
   
    安装过程可查看
    
     https://www.runoob.com/mysql/mysql-install.html
    
   
初学者建议安装5.7版本,8.0以上需要爬坑。
    
     4、Redis
    
   
本节可忽略,但是如果需要实现单设备登录、或者单点登录功能,需要在 redis 中为用户保留一份 token信息。
    安装教程查看
    
     https://www.runoob.com/redis/redis-install.html
    
   
    
    
    后端代码实现
   
先看入口文件 app.js
    
     app.js
    
   
const express = require("express");
const app = express();
const port = 3000
var path = require('path');
const {
   expressjwt} = require('express-jwt')
require("./config.js");
const Redis = require('./utils/redis.js'); 
// 解析 post 请求的 body 体
app.use(express.urlencoded({
    extended: false})); 
app.use(express.json())
var server = require('http').Server(app);
// 写在前面的路由不进行拦截
app.use("/account", require("./router/account.js")); // 登录相关页面路由
app.use("/mine", require("./router/mine.js")); 	// 我的页面路由
// 设置不需要验证的接口
let noAuth = ['/api/regist', '/api/login'];
// token 拦截
app.use(expressjwt({
    secret: global.config.SECRET_KEY, algorithms: ['HS256'] }).unless({
    path: noAuth }))
app.use(function (err, req, res, next) {
   
  if (err.name === 'UnauthorizedError') {
      
    res.status(401).send('invalid token')
  }
})
// 验证 redis ------  可以忽略,感兴趣的后期加上
app.use(function (req, res, next) {
   
	let url = req.url;
	if(noAuth.find(item=>{
   
		return item == url;
	})){
   
		next();
		return;
	}
	// 过滤不需要验证的接口
	
  let userID = req.auth.userID;
  let token = req.headers.authorization;
  
  let redisClient = new Redis();
  redisClient.getKey(`token_${
     userID}`).then(val => {
   
  	// 判断是否过期
  	if(val && token == val){
   
		next();
  	}else{
   
		res.status(401).send('invalid token')
	}
  })
})
// api 接口文件,和路由分开
app.use("/api", require("./router/api.js"));
server.listen(port, () => {
   
  console.log(`Example app listening on port ${
     port}`)
})
页面引用了 config.js,这个页面主要是配置一些公共信息,存入 global 全局变量中。
    
     config.js
    
   
global.config = {
   
	SECRET_KEY: 'just do it'
}
redis.js 实现了对 redis 字符串操作的封装,一个是读取 key 的值,一个是设置 key 的值和失效时间。
    
     redis.js
    
   
const redis = require('redis')
const client = redis.createClient(6379,'localhost') 
function redisClient(){
   
	this.getKey =  
