美文网首页工作生活
node+express+knexjs+mysql2+token

node+express+knexjs+mysql2+token

作者: JackeeM | 来源:发表于2019-07-03 13:52 被阅读0次

    使用架构

    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

    相关文章

      网友评论

        本文标题:node+express+knexjs+mysql2+token

        本文链接:https://www.haomeiwen.com/subject/jluqhctx.html