使用架构
express+knexjs+mysql2+token
实现功能
- 增删改查
- 登录token机制与401处理
- 统一容错处理
未实现功能
- 数据库事务
主程序
- express
数据库
- [mysql2]
- knexjs
token管理中间件
- 生成token jsonwebtoken
- 校验token express-jwt
常用中间件
先甩出一份 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管理中间件
- 生成token jsonwebtoken
- 校验token express-jwt
如何生成?
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并且有效的情况下,
}
));
拿到后就可以开始你的下一个逻辑 微笑
网友评论