zoukankan      html  css  js  c++  java
  • 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;
    

      

     

  • 相关阅读:
    Effective Java 19 Use interfaces only to define types
    Effective Java 18 Prefer interfaces to abstract classes
    Effective Java 17 Design and document for inheritance or else prohibit it
    Effective Java 16 Favor composition over inheritance
    Effective Java 15 Minimize mutability
    Effective Java 14 In public classes, use accessor methods, not public fields
    Effective Java 13 Minimize the accessibility of classes and members
    Effective Java 12 Consider implementing Comparable
    sencha touch SortableList 的使用
    sencha touch dataview 中添加 button 等复杂布局并添加监听事件
  • 原文地址:https://www.cnblogs.com/deng-jie/p/12787985.html
Copyright © 2011-2022 走看看