以 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,
// 本地的插件用 path
path: 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就是 options
const 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');