NodeJs使用jwt生成token以及使用express-jwt校验和解密token

/注:校验token,获取headers⾥里里的Authorization的token方法,要写在路由加载之前,静态资源之后

app.use(expressJWT({
  secret: PRIVATE_KEY
}).unless({
  path: ['/api/user/register','/api/user/login'] //⽩白名单,除了了这⾥里里写的地址,其他的URL都需要验证
}));

一、生成token

1、安装jsonwebtoken

npm install jsonwebtoken -S

 

2、在公共文件中定义一个秘钥和过期时间(单位是秒)

module.exports = {
    "PRIVITE_KEY":"我是秘钥",
    "EXPIRESD":60*60*24
}

3、在需要生成token的页面引入jsonwebtoken(路由页面)

// jwt生成token
var {PRIVITE_KEY,EXPIRESD} = require("../utils/store")
const jwt = require("jsonwebtoken");

//jwt.sign()方法可生成token,第一个参数写的用户信息进去(可以写其他的),第二个是秘钥,第三个是过期时间
let token = jwt.sign({username},PRIVITE_KEY,{expiresIn:EXPIRESD});

 

  

 

 

二、校验和解密token此方法写在静态资源加载之后,不然静态资源不能访问)

1、安装express-jw

npm install express-jwt

2、校验token,获取headers⾥里里的Authorization的token

前端token值格式 Bearer+token    这是express-jwt规定的前端格式
在入口文件app.js中引入express-jw以及token加密时使用的秘钥
const expressJWT = require('express-jwt');
var { PRIVITE_KEY } = require("./utils/store");
//使用此方法拦截所有请求看token是否正确(此方法写在静态资源加载之后,不然静态资源不能访问)
app.use(expressJWT({
  secret: PRIVATE_KEY
}).unless({
  path: ['/api/user/register','/api/user/login'] //⽩白名单,除了了这⾥里里写的地址,其他的URL都需要验证
}));

在app.js中的错误中间件定义token的处理
  // error handler
  app.use(function (err, req, res, next) {
      if (err.name === 'UnauthorizedError') {
        // 这个需要根据⾃自⼰己的业务逻辑来处理理
        res.status(401).send({code:-1,msg:'token验证失败'});
    }else {
      // set locals, only providing error in development
      res.locals.message = err.message;
      res.locals.error = req.app.get('env') === 'development' ? err : {};

      // render the error page
      res.status(err.status || 500);
      res.render('error');
    }
  });
 

 
在路由接口中可以使用req.user拿到token解密的值
 
 
 

 

路由页面如下

var express = require('express');
var router = express.Router();

var querySql = require("../db/index");
// md5加密key和方法
var {key} = require('../utils/store');
var {md5} = require("../utils/index")
// jwt生成token
var {PRIVITE_KEY,EXPIRESD} = require("../utils/store")
const jwt = require("jsonwebtoken");


// 登录接口
router.post("/login",async (req,res,next) => {
  try {
    // 对应前台的传参
    let {username,password} = req.body;
    // 跟数据库对应,看是否存在当前用户
    password = md5(`${password}${key}`);
    let result = await querySql("select * from user where username = ? and password = ?",[username,password]);
    if(result && result.length != 0){
      // 数据库有当前用户时返回token
      let token = jwt.sign({username},PRIVITE_KEY,{expiresIn:EXPIRESD});
      res.send({
        code:0,
        msg:"登录成功",
        token:token
      })
    }else {
      res.send({
        code:-1,
        msg:"用户名或者密码错误"
      })
    }
  } catch (error) {
    // p抛出异常并交由错误中间件处理
    console.log(error);
    next(error);
  }
})
// 注册接口
router.post('/register', async (req, res, next)=>{
  let {
    username,
    password,
    nickname
  } = req.body;
  try {
    // 查询当前用户名在不在数据库中(使用async方法后必须使用await方法才有值返回,不然返回promise对象)
    let user = await querySql("select * from user where username = ?", [username]);
    // 存在res即是数据库中有数据
    if (user && user.length != 0) {
      res.send({
        code: -1,
        msg: "用户已注册"
      })
    } else {
      // 对密码进行加密
      password = md5(`${password}${key}`);
      // async 和 await 向数据库插入数据
      await querySql("insert into user(username,password,nickname) values (?,?,?)", [username, password, nickname]);
      res.send({
        code: 0,
        msg: "注册成功"
      })
    }
  } catch (error) {
    console.log(error)
    next(error)
  }
});

// 查询用户信息接口
router.get("/info",async (req,res,next)=>{
  // 通过username获取用户信息
  console.log(req.user)
  let {username} = req.body;
  try {
    let userInfo = await querySql("select * from user where username = ?",[username]);
    res.send({
      code:0,
      userInfo:userInfo
    })
  } catch (error) {
    console.log(error);
    next(error);
  }  
})

module.exports = router;

  

app.js写法如下

var createError = require('http-errors');
var express = require('express');
var path = require('path');
var cookieParser = require('cookie-parser');
var logger = require('morgan');
var cors = require("cors");
// 使用express-jwt来进行token的解密和验证
const expressJWT = require('express-jwt');
var { PRIVITE_KEY } = require("./utils/store");
var indexRouter = require('./routes/index');
var usersRouter = require('./routes/users')
var app = express();
// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');
// 处理跨域
app.use(cors())
// 日志
app.use(logger('dev'));
// 使用post请求
app.use(express.json());
app.use(express.urlencoded({
  extended: false
}));
// 使用cookie
app.use(cookieParser());
// 访问静态资源目录
app.use(express.static(path.join(__dirname, 'public')));
// 校验token,获取headers⾥里里的Authorization的token,要写在路由加载之前,静态资源之后
app.use(expressJWT({
  secret: PRIVITE_KEY
}).unless({
  path: ['/api/user/register', '/api/user/login'] //⽩白名单,除了了这⾥里里写的地址,其他的URL都需要验证
}));

// 使用路由
app.use('/', indexRouter);
app.use('/api/user', usersRouter);

// catch 404 and forward to error handler
app.use(function (req, res, next) {
  next(createError(404));
});

// error handler
app.use(function (err, req, res, next) {
  if (err.name === 'UnauthorizedError') {
    // 这个需要根据⾃自⼰己的业务逻辑来处理理
    res.status(401).send({code:-1,msg:'token验证失败'});
  }else {
    // set locals, only providing error in development
    res.locals.message = err.message;
    res.locals.error = req.app.get('env') === 'development' ? err : {};

    // render the error page
    res.status(err.status || 500);
    res.render('error');
  }
});

module.exports = app;

  

 

原文地址:https://www.cnblogs.com/deng-jie/p/12787985.html