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.authorization
token = token
? token.split('Bearer ')[1] // Bearer空格token数据
: null
if (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
} } }
```typescript
config.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',
},
],
});