以 egg-auth为例,如何写一个规范的 egg中间件
可以查看,node_modules目录下的 egg-开头的,例如 egg-static静态目录插件,查看egg的插件规范。
image.png

config

/config/plugin.js 注册 egg插件

  1. const path = require('path');
  2. const pathJoin = url => path.join(__dirname, url);
  3. // 模板引擎
  4. exports.nunjucks = {
  5. enable: true,
  6. package: 'egg-view-nunjucks', // npm安装的插件用 package
  7. };
  8. // 登录鉴权
  9. exports.auth = {
  10. enable: true,
  11. // 本地的插件用 path
  12. path: pathJoin('../lib/plugin/egg-auth'),
  13. };

package 和 path是互斥的,只能使用一个

  • package npm安装的插件,用 package
  • path 本地插件用 path

config.default.js

配置插件参数,例如 白名单

  1. // exclude 不需要验证的路由
  2. config.auth = {
  3. exclude: ['/home', '/login', 'logout']
  4. }

options 参数里获取 config.auth的 exclude配置

app

middleware

/lib/plugin/egg-auth/app/middleware/auth.js

  1. 'use strict';
  2. module.exports = options => {
  3. return async (ctx, next) => {
  4. const { url } = ctx.request;
  5. const { user } = ctx.session;
  6. // const user = await ctx.app.redis.get(ctx.username);
  7. // 比较 redis 里存的用户名和请求传过来的是否相等
  8. // const user = username ? username === token : username;
  9. // '/index.html?id=123&name=ok'.split('?')
  10. const [ path ] = url.split('?');
  11. // 排除的白名单, config.default.js里面的 config.auth就是 options
  12. const include = options.exclude?.includes(path);
  13. if (!user && !include) {
  14. ctx.redirect(`/login?callback=${url}`);
  15. // ctx.body = {
  16. // status: 1001,
  17. // message: '用户未登录',
  18. // };
  19. return; // 必须要 return,否则下面的代码会执行
  20. }
  21. await next();
  22. };
  23. };

package.json

  1. {
  2. "name": "egg-auth",
  3. "version": "1.0.0",
  4. "eggPlugin": {
  5. "name": "auth"
  6. },
  7. "dependencies": {
  8. }
  9. }

coreMiddleware 注册中间件

app.config.coreMiddleware 是个数组

  1. app.config.coreMiddleware.push('auth');