• Egg入门学习(三)---理解中间件作用


    Egg是基于koa的,因此Egg的中间件和Koa的中间件是类似的。都是基于洋葱圈模型的。

    在Egg中,比如我想禁用某些IP地址来访问我们的网页的时候,在egg.js中我们可以使用中间件来实现这个功能,中间件的作用无非就是说在Egg的外层在包一层来判断某些事情是否符合要求,也就是在洋葱圈模型外面再进行包一层。
    在Egg入门二学习中(https://www.cnblogs.com/tugenhua0707/p/10226799.html), 我们最后的项目的目录结构如下:

    egg-demo2
    ├── app
    │   ├── controller
    │   │   └── home.js
    |   |   |-- index.js
    │   └── router.js
    │   ├──public
    |   | |---css
    |   | | |-- index.css
    |   | |---js
    |   | | |-- index.js
    |   |--- view
    |   | |-- index
    |   | | |-- list.tpl(模板文件list)
    |   |--- service
    |   | |--- index.js
    ├── config
    │   └── config.default.js
    └── package.json

    在Egg中,中间件也有自己的配置和目录,因此在Egg中约定了中间件是放在 app/middleware 目录中的文件。该文件需要exports一个普通的function. 因此整个项目的目录变成如下这个样子:

    egg-demo2
    ├── app
    │   ├── controller                # 用于解析用户的输入,处理后返回响应的结果
    │   │   └── home.js
    |   |   |-- index.js
    │   └── router.js                 # 用于配置url路由的配置规则
    │   ├──public                     # 资源文件目录
    |   | |---css
    |   | | |-- index.css
    |   | |---js
    |   | | |-- index.js
    |   |--- view                     # 存放模板文件的目录
    |   | |-- index
    |   | | |-- list.tpl(模板文件list)
    |   |--- service                  # 编写业务逻辑的目录
    |   | |--- index.js
    |   |--- middleware               # 用于编写中间件的目录
    |   | |--- xxx.js
    ├── config                        # 相关的配置文件
    │   └── config.default.js
    └── package.json

    编写中间件

    我们在 app/middleware 目录中 新建一个 forbidIp.js 文件,该文件的作用是 禁用某些ip地址访问我们的网页。因此代码编写如下:

    module.exports = (options, app) => {
      return async function forbidIp(ctx, next) {
        console.log(options);
        console.log('---------');
        console.log(app);
    
        // 需要被屏蔽的id
        const ids = options.forbidips;
        // 获取客户端的ip
        const clientIp = ctx.request.ip;
    
        const isHasIp = ids.some(val => {
          if (val === clientIp) {
            return true;
          }
          return false;
        });
        if (isHasIp) {
          ctx.status = 403;
          ctx.body = '您的IP已经被屏蔽掉了';
        } else {
          await next();
        }
      }
    }

    使用中间件

    如上中间件编写完成后,我们还需要手动挂载中间件。因此我们需要在 config/config.default.js 中加入下面的配置就可以完成了中间件的开启和配置:代码如下:

    // 配置需要的中间件,数组的顺序即为中间件加载的顺序
    exports.middleware = [
      'forbidIp'
    ];
    // 上面中间件的配置 ip
    exports.forbidIp = {
      forbidips: [
        '192.168.1.12',
        '127.0.0.1',
      ]
    }

    注意:如上 exports.middleware = ['forbidIp']; 该 forbidIp 指向与 app/middleware 中的 forbidIp.js, 因此需要注意大小写。也就是说是 forbidIp.js 中间件。然后下面的 exports.forbidIp = {}; forbidIp中间件的名字也需要一样的。exports.forbidIp 里面的对象就是中间件的ip配置了。

    如上中间件代码,它接收两个参数:options 和 app;
    options参数指的是 app.config[${middlewareName}]传进来。我们在 如上中间件代码中打印 options; console.log(options); 及 打印 console.log(app); 如下图所示:

    可以看到 console.log(options); options参数的值就是 config配置项中的 

    {
      forbidips: [
        '192.168.1.12',
        '127.0.0.1',
      ]
    }

    打印 config.log(app) 的值,如上图所示;它的含义是指 当前应用Application的实列。

    因此我们继续访问 http://127.0.0.1:7001/ 后可以看到如下信息,页面被禁用了。如下图所示:

    如果我们继续把 config/config.default.js 配置代码改成其他的ip地址,代码如下:

    // 配置需要的中间件,数组的顺序即为中间件加载的顺序
    exports.middleware = [
      'forbidIp'
    ];
    // 上面中间件的配置 ip
    exports.forbidIp = {
      forbidips: [
        '192.168.1.12',
        '127.0.0.12'
      ]
    }

    我们继续访问 http://127.0.0.1:7001/ 后,页面就正常了。如下所示:

    二:在 router.js路由中使用中间件。

    如上使用中间件都是全局的,每一次请求都会处理的,但是有时候我想针对单个路由生校的话,我们就不需要再 config中配置了。我们直接在路由中配置即可。

    router.js在未使用中间件处理之前代码是如下:

    module.exports = app => {
      const { router, controller } = app;
      router.get('/', controller.home.index);
      router.get('/index', controller.index.list);
    }

    现在我们需要在 router.get('/'); 下使用禁用ip中间件,因此我们可以先注释掉 config中全局的中间件配置。我们可以直接在 router.js 下处理即可,如下代码所示:

    首先:config/config.default.js 代码注释掉中间件:

    /*
    // 配置需要的中间件,数组的顺序即为中间件加载的顺序
    exports.middleware = [
      'forbidIp'
    ];
    // 上面中间件的配置 ip
    exports.forbidIp = {
      forbidips: [
        '192.168.1.12',
        '127.0.0.12'
      ]
    }
    */

    然后在单个路由中使用中间件, router.js的代码如下:

    module.exports = app => {
      const { router, controller } = app;
    
      // 路由中使用中间件
      const forbidIp = app.middleware.forbidIp({
        forbidips: [
          '127.0.0.1'
        ]
      });
    
      router.get('/', forbidIp, controller.home.index);
      router.get('/index', controller.index.list);
    }

    然后我们继续访问 http://127.0.0.1:7001/ 后,页面也会提示该ip地址已经被屏蔽掉了。

    更多的关于中间件配置介绍,请看官网中介绍的(https://eggjs.org/zh-cn/basics/middleware.html)

    查看github源码中中间件代码

  • 相关阅读:
    使用replaceAll替换“/”为“/”
    如何在Lucene里面进行数字范围搜索 (Numeric Range Query)
    Java中的参数传递
    安装配置WordPress 3.0的多站点功能
    Apache Hadoop 项目介绍
    Java中的Set操作
    使用Desktop API in Java SE 6打开文件或者网页
    Java集合(转帖)
    数据结构牛客网习题纠错130
    PAT 1045 Favorite Color Stripe[dp][难]
  • 原文地址:https://www.cnblogs.com/tugenhua0707/p/10247637.html
Copyright © 2020-2023  润新知