以 egg-auth为例,如何写一个规范的 egg中间件
可以查看,node_modules目录下的 egg-开头的,例如 egg-static静态目录插件,查看egg的插件规范。
config
/config/plugin.js 注册 egg插件
const path = require('path');const pathJoin = url => path.join(__dirname, url);// 模板引擎exports.nunjucks = {enable: true,package: 'egg-view-nunjucks', // npm安装的插件用 package};// 登录鉴权exports.auth = {enable: true,// 本地的插件用 pathpath: pathJoin('../lib/plugin/egg-auth'),};
package 和 path是互斥的,只能使用一个
- package npm安装的插件,用 package
 - path 本地插件用 path
 
config.default.js
配置插件参数,例如 白名单
// exclude 不需要验证的路由config.auth = {exclude: ['/home', '/login', 'logout']}
options 参数里获取 config.auth的 exclude配置
app
middleware
/lib/plugin/egg-auth/app/middleware/auth.js
'use strict';module.exports = options => {return async (ctx, next) => {const { url } = ctx.request;const { user } = ctx.session;// const user = await ctx.app.redis.get(ctx.username);// 比较 redis 里存的用户名和请求传过来的是否相等// const user = username ? username === token : username;// '/index.html?id=123&name=ok'.split('?')const [ path ] = url.split('?');// 排除的白名单, config.default.js里面的 config.auth就是 optionsconst include = options.exclude?.includes(path);if (!user && !include) {ctx.redirect(`/login?callback=${url}`);// ctx.body = {// status: 1001,// message: '用户未登录',// };return; // 必须要 return,否则下面的代码会执行}await next();};};
package.json
{"name": "egg-auth","version": "1.0.0","eggPlugin": {"name": "auth"},"dependencies": {}}
coreMiddleware 注册中间件
app.config.coreMiddleware 是个数组
app.config.coreMiddleware.push('auth');
