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源码中中间件代码

原文地址:https://www.cnblogs.com/tugenhua0707/p/10247637.html

时间: 2024-08-16 06:50:32

Egg入门学习(三)---理解中间件作用的相关文章

MongoDB入门学习(三):MongoDB的增删查改

对于我们这种菜鸟来说,最重要的不是数据库的管理,也不是数据库的性能,更不是数据库的扩展,而是怎么用好这款数据库,也就是一个数据库提供的最核心的功能,增删查改. 因为MongoDB存储数据都是以文档的模式,所以在操作它的数据时,也是以文档为单位的.那么我们实现增删查改也是以文档为基础,不知道文档是什么的同学可以看看上篇介绍的基本概念. 1.插入文档 向MongoDB集合中插入文档的基本方法是insert: 单个插入 > document = {key : value} > db.collecti

Objective C 快速入门学习三

1.数据类型 和C语言基本一样. 有一个特别数据类型id,可以储存任何类型的对象,它是实现多态和动态绑定的基础. Objective-C 2.程序结构 Objective-C和C的程序结构一模一样,具体用法相同. 顺序.循环.选择 3.基本上Objective-C兼容了C语言所有特点,包括数组.结构.字符串.联合,它们不是对象,面向过程式.建议直接使用相关框架下的相关类,面对对象编程. Objective C 快速入门学习三

正则学习三 (小括号作用)

var reg=/^18|19$/ //结果可匹配:18,19, 189, 119, 819,181, 1819 意思为: *18或者19 *以18开头或以19结尾, *以1开头,9结尾,当中包含8或1 var reg=/^(18|19)$/ //结果:18, 19 //():正则中的分组,也可以理解为一个大正则中的一个小正则(包起来部分是一个整体),在正则中可以使用小括号改变一些默认优先级//小分组第二个作用:分组引用//小分组第三个作用:分组捕获 //分组引用:\1或\2...出现和第n个分

Egg入门学习(一)

一:什么是Egg? 它能做什么?Egg.js是nodejs的一个框架,它是基于koa框架的基础之上的上层框架,它继承了koa的,它可以帮助开发人员提高开发效率和维护成本.Egg约定了一些规则,在开发中,我们可以按照一套统一的约定进行应用开发,团队内部使用这种方式开发可以减少开发人员的学习成本. Express也是Node.js的一个框架,express简单且扩展性强,但是express框架缺少了一些约定,不同的开发者会写出不同的代码,适合做个人项目,不太适合团队开发,而Egg它约定了一些规则,对

入门学习三

看“编码之外”提供的JAVA学习视频,觉得很难.于是寻找另外的参照物. 试过“儿童编程”,其实是要学费的.好懂,却觉得交学费时机不成熟. 于是,我又找到“易语言”.——这来自于“我要自学网”.看了几天,觉得便于操作.也懂得多练习“写代码”的熟能生巧逻辑. 由此,我获得一个认识,一切网页web显示,它固然有其“源代码”——你在任何的位置,右击鼠标,均会显示“查看网页源代码”,在另一个维度,就是称呼其为一段程序.信息越复杂,数据越庞大,包含的“程序”就越多.大多数人是迷失在“混沌的信息海洋里面”了的

C++入门学习——explicit关键字的作用

C++ 语言可以定义如何将其他类型的对象隐式转换为我们的类类型, 或将我们的类类型的对象隐式转换为其他类型. 下面为类类型的隐式转换的示例代码: #include <iostream> using namespace std; class A { public: A(int temp) //普通构造函数 { a = temp; cout << "普通构造函数: a= " << a << endl; } A(const A &tem

dubbo入门学习(三)-----dubbo整合springboot

springboot节省了大量的精力去配置各种bean,因此通过一个简单的demo来整合springboot与dubbo 一.创建boot-user-service-provider 本篇博文基于上篇中的dubbo项目,整体工程如下: 1.pom.xml <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0"

OpenGL入门学习

说起编程作图,大概还有很多人想起TC的#include <graphics.h>吧? 但是各位是否想过,那些画面绚丽的PC游戏是如何编写出来的?就靠TC那可怜的640*480分辨率.16色来做吗?显然是不行的. 本帖的目的是让大家放弃TC的老旧图形接口,让大家接触一些新事物. OpenGL作为当前主流的图形API之一,它在一些场合具有比DirectX更优越的特性. 1.与C语言紧密结合. OpenGL命令最初就是用C语言函数来进行描述的,对于学习过C语言的人来讲,OpenGL是容易理解和学习的

HTML与CSS入门——第三章 理解HTML和XHTML的关系

知识点: 1.以HTML创建一个简单网页的方法 2.包含每个网页必须有的所有HTML标签的方法 3.用段落和换行组织页面的方法 4.用标题组织内容的方法 5.HTML.XML.XHTML和HTML5之间的差别 3.1 从一个简单的网页开始: 作者建议:从简单的文本编辑器开始学习,之后再转向可视化工具. 扩展名支持:.htm以及.html 如.jsp,.asp,.php之类的文件类型使用超出了HTML范围的服务器端技术,需要专门的服务端支持.比如Apache服务器 3.2 每个XHMTL网页必须有