node+express+knexjs+mysql2+token

使用架构

express+knexjs+mysql2+token

实现功能

  • 增删改查
  • 登录token机制与401处理
  • 统一容错处理

未实现功能

  • 数据库事务

主程序

  • express

数据库

token管理中间件

常用中间件

  • 唯一id生成器 uuid
  • 热更新 nodemon
    可全局安装,替代node使用
  • 时间格式化 [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"
  }
}

开始搭建


连接数据库与增删改查

建立路由文件

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)

/**
 * 获取学生信息
 * 所有数据
 */
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})
  }
));


/**
 * 获取所有学生信息
 * 分页数据
 */
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配置

导入2个包

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: '账号或者密码错误'
      })
    }
  }
));

核心代码

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

let result = jwt.sign({ //加密JSON
  id: user[0].id,
  username: user[0].username
}, secretKey, { //秘钥
  expiresIn: 10h //保存时间
})

如何校验
新建auth.js

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

const {
  secretKey
} = require('../config');
// express-jwt中间件帮我们自动做了token的验证以及错误处理,所以一般情况下我们按照格式书写就没问题,其中unless放的就是你想要不检验token的api。
/**
 * 客户端请求携带token的机制为 
 * 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)

如何调用?

请求头里面加上token参数即可

 header:{
   authorization: Bearer token-value
 }

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

token检验通过后会把检验结果next()到下一个中间件在req.user中可以取出存入的JSON串

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

拿到后就可以开始你的下一个逻辑 微笑

最后附上目录

image.png
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容