# 用户鉴权中间件
源码:https://github.com/push-over/egg-example/blob/70dc0ac730/app/middleware/auth.ts
在本节中我将带大家实现一个用户鉴权的中间件,那什么是中间件呢? 在NodeJS中,中间件主要是指封装所有Http 请求细节处理的方法。一次 Http 请求通常包含很多工作,如记录日志、ip过滤、查询字符串、请求体解析、Cookie处理、权限验证、参数验证、异常处理等,但对于Web应用而言,并不希望接触到这么多细节性的处理,因此引入中间件来简化和隔离这些基础设施与业务逻辑之间的细节,让开发者能够关注在业务的开发上,以达到提升开发效率的目的。
# 编写中间件
写法:我们先来通过编写 AuthMiddleware 中间件,来看看中间件的写法。
import { Context, Application } from 'egg';
// AuthMiddleware 名字随意
export default function AuthMiddleware(_options: any, _app: Application) {
return async (ctx: Context, next: any) => {
};
}
@前端进阶之旅: 代码已经复制到剪贴板
# 配置
一般来说中间件也会有自己的配置。在框架中,一个完整的中间件是包含了配置处理的。我们约定一个中间件是一个放置在 app/middleware 目录下的单独文件,它需要 exports 一个普通的 function,接受两个参数:
- options: 中间件的配置项,框架会将
app.config[${middlewareName}]传递进来。 - app: 当前应用 Application 的实例。
# 实现中间件方法
在大致了解后,接下来我们来实现这个方法
app/middleware/auth.ts:
import { Context, Application } from 'egg';
export default function AuthMiddleware(_options: any, _app: Application) {
return async (ctx: Context, next: any) => {
// 为了方便调试,开发者工具 graphiql 如果开启的话则放行
if (ctx.app.config.graphql.graphiql) {
await next();
return;
}
// 白名单:有些操作我们是不需要鉴权的
const whitelist = [ 'login', 'register', 'sendSms', 'githubURL' ];
const body = ctx.request.body;
// 如果不在白名单中验证 token
if (!whitelist.includes(body.operationName)) {
const uuid = ctx.request.header.authorization;
// 拿到客户端传的 token 做键去 redis 中取
const token = ctx.helper.JSONParse(await ctx.service.redis.get(uuid)) || {};
const { name } = token;
// 取到了放行,反之无效 401
if (name) {
await next();
} else {
ctx.body = { message: '访问令牌鉴权无效,请重新登陆获取!' };
ctx.status = 401;
}
} else {
await next();
}
};
}
@前端进阶之旅: 代码已经复制到剪贴板
# 使用中间件
中间件编写完成后,我们还需要手动挂载。在应用中,我们可以完全通过配置来加载自定义的中间件,并决定它们的顺序。
如果我们需要加载上面的 auth 中间件,在 config.default.ts 中加入下面的配置就完成了中间件的开启和配置:

该配置最终将在启动时合并到
app.config.appMiddleware。
# 小结
在本篇中介绍了什么是中间件以及中间件的用途。并在项目中编编写了一个用户鉴权的中间级,配置并使用该中间件。
