node+express+knexjs+mysql2+token

使用架構(gòu)

express+knexjs+mysql2+token

實(shí)現(xiàn)功能

  • 增刪改查
  • 登錄token機(jī)制與401處理
  • 統(tǒng)一容錯(cuò)處理

未實(shí)現(xiàn)功能

  • 數(shù)據(jù)庫(kù)事務(wù)

主程序

  • express

數(shù)據(jù)庫(kù)

token管理中間件

常用中間件

  • 唯一id生成器 uuid
  • 熱更新 nodemon
    可全局安裝,替代node使用
  • 時(shí)間格式化 [moment]
  • id生成器 [node-uuid]

先甩出一份 package.json

{
  "name": "express-cli",
  "version": "1.0.0",
  "private": true,
  "scripts": {
    "dev": "nodemon ./bin/www"
  },
  "dependencies": {
    "cookie-parser": "~1.4.4",
    "cross-env": "^5.2.0",
    "debug": "~2.6.9",
    "express": "~4.16.1",
    "express-jwt": "^5.3.1",
    "http-errors": "~1.6.3",
    "jsonwebtoken": "^8.5.1",
    "knex": "^0.17.6",
    "moment": "^2.24.0",
    "morgan": "~1.9.1",
    "mysql2": "^1.6.5",
    "node-uuid": "^1.4.8"
  }
}

開(kāi)始搭建


連接數(shù)據(jù)庫(kù)與增刪改查

建立路由文件

const mysql = require('knex')({
  client: 'mysql2',
  connection: {
    host : '127.0.0.1',
    user : 'root',
    password : '123456',
    database : 'school'
  }
});

module.exports = mysql
var express = require('express');
var router = express.Router();
let ayc = require("../sync");
let studentDao = require("../dao/student")

// console.log(mysql)

/**
 * 獲取學(xué)生信息
 * 所有數(shù)據(jù)
 */
router.get('/findList', ayc.asyncHandler(
  async function (req, res, next) {
    const {
      name,
      age,
    } = req.query;

    const result = await studentDao.findList({
      name,
      age
    })
    res.httpBackSuccess({result})
  }
));


/**
 * 獲取所有學(xué)生信息
 * 分頁(yè)數(shù)據(jù)
 */
router.get('/findPage', ayc.asyncHandler(
  async function (req, res, next) {
    const {
      pageNo = 1,
      pageSize = 20,
      name,
      age,
    } = req.query;

    const result = await studentDao.findPage({
      pageNo,
      pageSize,
      name,
      age
    })
    res.httpBackSuccess({result})
  }
));

router.post('/add', ayc.asyncHandler(
  async function (req, res, next) {
    const {
      name,
      age,
      classId,
      sex,
      email
    } = req.body;

    await studentDao.add({
      name,
      age,
      classId,
      sex,
      email,
      createdAt: new Date(),
      updatedAt: new Date(),
    })
    res.httpBackSuccess({})
  }
));

router.post('/update', ayc.asyncHandler(
  async function (req, res, next) {
    const {
      id,
      name,
      age,
      classId,
      sex,
      email
    } = req.body;

    await studentDao.update(id,{
      name,
      age,
      classId,
      sex,
      email,
      updatedAt: new Date(),
    })
    res.httpBackSuccess({})
  }
));

router.post('/delet', ayc.asyncHandler(
  async function (req, res, next) {
    const {
      id
    } = req.body;
    console.log(id)
    await studentDao.delet(id)
    res.httpBackSuccess({msg: '刪除成功'})
  }
));

module.exports = router;

登錄與token配置

導(dǎo)入2個(gè)包

token管理中間件

如何生成?

router.post('/login', ayc.asyncHandler(
  async function (req, res, next) {
    const {
      username,
      password,
    } = req.body;
    let user = await managerDao.findByUsername(username);
    console.log(user)
    if (user.length === 0) {
      res.httpBackError({
        msg: '用戶不存在'
      })
      return
    }
    if (md5(password) === user[0].password) {
      let result = jwt.sign({
        id: user[0].id,
        username: user[0].username
      }, secretKey, {
        expiresIn: 60 * 1
      })
      console.log('result'+result)
      res.httpBackSuccess({
        msg: '登錄成功',
        result
      })
    } else {
      res.httpBackError({
        msg: '賬號(hào)或者密碼錯(cuò)誤'
      })
    }
  }
));

核心代碼

const jwt = require("jsonwebtoken");
const {
  secretKey  //秘鑰
} = require('../../config');

let result = jwt.sign({ //加密JSON
  id: user[0].id,
  username: user[0].username
}, secretKey, { //秘鑰
  expiresIn: 10h //保存時(shí)間
})

如何校驗(yàn)
新建auth.js

// jwt.js,token中間件
const expressJwt = require("express-jwt");

const {
  secretKey
} = require('../config');
// express-jwt中間件幫我們自動(dòng)做了token的驗(yàn)證以及錯(cuò)誤處理,所以一般情況下我們按照格式書寫就沒(méi)問(wèn)題,其中unless放的就是你想要不檢驗(yàn)token的api。
/**
 * 客戶端請(qǐng)求攜帶token的機(jī)制為 
 * header:{
 *  authorization: Bearer token-value
 *  (小寫)authorization:Bearer+空格+token
 * }
 */
const jwtAuth = expressJwt({
  secret: secretKey
}).unless({
  path: ["/manager/login"]
});

module.exports = jwtAuth;

在app.js中引入

var jwtAuth = require('./utils/auth');
app.use(jwtAuth)

如何調(diào)用?

請(qǐng)求頭里面加上token參數(shù)即可

 header:{
   authorization: Bearer token-value
 }

如何拿到存入的信息如用戶id

token檢驗(yàn)通過(guò)后會(huì)把檢驗(yàn)結(jié)果next()到下一個(gè)中間件在req.user中可以取出存入的JSON串

router.get('/findList', ayc.asyncHandler(
  async function (req, res, next) {
    console.log(req.user) // 帶上token并且有效的情況下,
  }
));

拿到后就可以開(kāi)始你的下一個(gè)邏輯 微笑

最后附上目錄

image.png
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容