1.1生成token
安装 npm jsonwebtoken
config.jwt = {secret: 'a6e8561e-58df-4715-aa21-b5d1a091e71a',expiresIn: '1d'}
const jwt = require('jsonwebtoken');createToken(data) {const token = jwt.sign(data, this.app.config.jwt.secret, {expiresIn: this.app.config.jwt.expiresIn})return token}
1.2 自动验证token
利用中间件 进行token验证, 并将登录用户信息存储到ctx中, 供后续中间件使用
module.exports = (options = { required: true }) => {return async (ctx, next) => {// 1. 获取请求头中的 token 数据let token = ctx.headers.authorizationtoken = token? token.split('Bearer ')[1] // Bearer空格token数据: nullif (token) {try {// 3. token 有效,根据 userId 获取用户数据挂载到 ctx 对象中给后续中间件使用const data = ctx.service.user.verifyToken(token)ctx.user = await ctx.model.User.findById(data.userId)} catch (err) {ctx.throw(401)}} else if (options.required) {ctx.throw(401)}// 4. next 执行后续中间件await next()}}
// 引入 auth , 在需要token 验证的接口里 写入auth'use strict';/*** @param {Egg.Application} app - egg application*/module.exports = app => {const { router, controller } = app;const auth = app.middleware.auth()router.prefix('/api/v1') // 设置基础路径router.post('/create', controller.user.create);router.post('/users/login', controller.user.login);router.get('/user', auth, controller.user.getCurrentUser);};
1.3 密码加密
安装 npm crypto
const crypto = require('crypto')const _ = require('lodash')exports.md5 = str => {return crypto.createHash('md5').update(str).digest('hex')}exports._ = _
data.password = this.ctx.helper.md5(data.password)
2、表单验证
- egg-validate 验证插件:https://github.com/eggjs/egg-validate
- parameter 验证规则文档:https://github.com/node-modules/parameter
安装 npm egg-validate
exports.validate = {enable: true,package: 'egg-validate'}
3、配置异统一异常处理
- https://eggjs.org/zh-cn/core/error-handling.html
https://eggjs.org/zh-cn/basics/middleware.html ```typescript module.exports = () => { // 外层函数负责接收参数 // 返回一个中间件处理函数 return async function errorHandler (ctx, next) { try {
await next()
} catch (err) {
// 所有的异常都在 app 上触发一个 error 事件,框架会记录一条错误日志ctx.app.emit('error', err, ctx)const status = err.status || 500// 生产环境时 500 错误的详细错误内容不返回给客户端,因为可能包含敏感信息const error =status === 500 && ctx.app.config.env === 'prod'? 'Internal Server Error': err.message// 从 error 对象上读出各个属性,设置到响应中ctx.body = { error }if (status === 422) {ctx.body.detail = err.errors}ctx.status = status
} } }
```typescriptconfig.middleware = ['errorHandler']
1、this.ctx.validate({username: { type: 'string' },email: { type: 'email' },password: { type: 'string' },});2、this.ctx.throw(422, 'validation Failed', {errors: [{code: 'invalid',field: 'email',message: 'has already exists',},],});
