node.js实现token验证——从数据库验证登录到redis存储

  • Post author:
  • Post category:其他




前言

做过前后端分离项目的同学应该都做过 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 = 



版权声明:本文为weixin_43930421原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。