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;

  

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM