# 过滤器

# 什么是过滤器?

过滤器可以在业务云函数执行之前(或之后),统一拦截,进行过滤后再放行。

# 重要提示

*【重要】示例代码在目录router/middleware/modules/

# 我用自定义过滤器可以做什么?

# 自定义过滤器使用场景1 - 电商多店店铺管理系统后台
  • 1、使用自定义过滤器拦截当前登录用户
  • 2、检查该用户是否有权限操作该店铺
  • 3、如有权限,则同时将店铺信息直接回传给业务云函数
  • 4、在业务云函数的内置变量 filterResponse 中可直接获得当前操作的店铺的信息
自定义过滤器支持正则匹配请求路径。
自定义过滤器支持层级 越小越先执行
1
2

# 框架内置以下过滤器:(无需配置,已自动生效,编写同ID的过滤器可以覆盖内置过滤器)

过滤器ID 正则规则 层级 类型 说明
pub /pub/ 100 onActionExecuting 所有人都可以访问,不进行过滤
kh /kh/ 200 onActionExecuting 用户token过滤器,检测用户是否已登录
sys /sys/ 300 onActionExecuting 云函数层的权限过滤器,检测用户是否有此业务云函数的执行权限

# 中间件参数说明

参数 说明 类型 默认值 可选值
id 中间件ID,全局必须唯一,相同中间件ID会被覆盖 String - -
regExp 中间件的正则匹配规则(支持数组) String Array -
description 中间的描述 String - -
index 中间件的执行顺序,值越小越先执行 Number - -
mode 中间件的模式,详情见下方 String onActionExecuting 见下方mode参数说明
enable 是否启动该中间件 Boolean false true
main 执行的函数 async function(event, serviceRes) - -

# mode参数说明

类型 说明
onActionExecuting 在action执行前执行
onActionExecuted 在action执行后执行
onActionIntercepted 在action被其他中间件拦截后执行
onActionError 在action执行异常时执行

# 自定义过滤器代码示例

# 单店版

/**
 * 店铺权限过滤器示例
 */
module.exports = [
  {
    id: "shopManage",
    regExp: "^client/shop/manage/(.*)",
    description: "店铺操作接口需要检测用户是否有权限",
    index: 310,// 此处必须>300 因为检测用户是否登录的过滤器的index是200(sys是300,因此为了能通用,建议填大于300的值)(越小越先执行)
    mode:"onActionExecuting", 
    enable:true, // 通过设置enable=false可以关闭该中间件
    main: async function(event) {
      let { util, filterResponse } = event;
      let { vk , db, _ } = util;
      let { userInfo = {} } = filterResponse; // 此处的 userInfo 是 kh 过滤器传过来的(kh的index是200)
      let { role = [] } = userInfo;
      let res = { code : 0, msg : 'ok' };
      // 用户没有shopManage角色则拦截。(拦截后后面的云函数将不会运行,达到了简单的权限控制效果)
      if(role.indexOf("shopManage") === -1){
        return { code : -1, msg : '无权限' };
      }
      return res;
    }
  }
]


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

# 多店版(多商家版本)

即用户A只能操作自己的店铺A,不可以操作店铺B

/**
 * 多店版(多商家版本)店铺权限过滤器示例,此仅为示例,实际需要修改成与你系统逻辑相符合才行。
 */
module.exports = [
  {
    id: "shopManage",
    // 这里代表的是哪些云函数需要进行判断权限
    regExp: [
    	"^client/business/(.*)kh/",
    	"^client/business/(.*)sys/"
    ],
    description: "需要判断用户是否有权限操作此店铺",
    index: 310,// 此处必须>300 因为检测用户是否登录的过滤器的index是200(sys是300,因此为了能通用,建议填大于300的值)(越小越先执行)
    mode:"onActionExecuting", 
    enable:true, // 通过设置enable=false可以关闭该中间件
    main: async function(event) {
      let { data = {}, util, filterResponse } = event;
      let { vk , db, _ } = util;
      let { userInfo = {} } = filterResponse;
      let { shop_ids = [] } = userInfo;
      // 此 shop_id 为用户前端传过来的,因此我们需要在此进行判断,此用户是否有权限可操作这个该店铺
      let { shop_id } = data;
      let res = { code : 0, msg : 'ok' };
      if (vk.pubfn.isNull(shop_id)) {
      	return { code : -1, msg : `店铺id不能为空` };
      }
      if (shop_ids.indexOf(shop_id) === -1) {
      	return { code : -1, msg : `无权限操作店铺【${shop_id}` };
      }
      return res;
    }
  }
]


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

# 过滤器可以有很多种用途,权限判断只是其中一种用途,还可以

1、权限校验
2、统一对对外的接口进行加密、解密
3、写日志
4、对请求参数进行过滤处理
5、对返回给前端的数据进行过滤处理
6、等等
1
2
3
4
5
6

# 如何在业务函数获得过滤器传给业务函数的数据?


'use strict';
module.exports = {
  main: async(event) = >{
    // filterResponse 为过滤器传给业务函数的数据
    let { filterResponse } = event;
    /**
     * 自定义过滤器检测了用户token已通过
     * 且通过用户token获得了用户信息和用户当前登录的店铺信息,并传给业务函数
     */
    let res = {
      code: 0,
      msg: '',
      shopInfo : filterResponse.shopInfo,
      userInfo : filterResponse.userInfo 
    };

   
    return res;
  }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
最后修改时间: 12/11/2021, 16:13:25