Firebase 可调用函数的中间件

2023-11-27

With Firebase HTTP 函数,我们可以安装express并使用中间件。中间件对于在函数执行之前检查先决条件非常有用(除其他外)。例如,我们可以在中间件中检查身份验证、授权等,这样就不需要在每个端点定义中重复它们。

开发人员如何实现同样的目标Firebase 可调用函数?当您有大量可调用函数时,如何提取通常位于链式中间件中的所有功能?


似乎没有现成的可调用函数中间件框架,因此受到启发this,我自己卷了。 NPM 上有一些通用的链式中间件框架,但我需要的中间件非常简单,以至于构建自己的中间件比配置库来使用可调用函数更容易。

可选:如果您使用 TypeScript,则中间件的类型声明:

export type Middleware = (
  data: any,
  context: functions.https.CallableContext,
  next: (
    data: any,
    context: functions.https.CallableContext,
  ) => Promise<any>,
) => Promise<any>;

中间件框架如下:

export const withMiddlewares = (
  middlewares: Middleware[],
  handler: Handler,
) => (data: any, context: functions.https.CallableContext) => {
  const chainMiddlewares = ([
    firstMiddleware,
    ...restOfMiddlewares
  ]: Middleware[]) => {
    if (firstMiddleware)
      return (
        data: any,
        context: functions.https.CallableContext,
      ): Promise<any> => {
        try {
          return firstMiddleware(
            data,
            context,
            chainMiddlewares(restOfMiddlewares),
          );
        } catch (error) {
          return Promise.reject(error);
        }
      };

    return handler;
  };

  return chainMiddlewares(middlewares)(data, context);
};

要使用它,您需要附加withMiddlewares任何可调用函数。例如:

export const myCallableFunction = functions.https.onCall(
  withMiddlewares([assertAppCheck, assertAuthenticated], async (data, context) => {
    // Your callable function handler
  }),
);

上面的例子中使用了2个中间件。他们被锁链如此assertAppCheck首先被调用,然后assertAuthenticated,只有在他们都通过后,你的传手才会被叫到。

这两个中间件是:

断言应用检查:

/**
 * Ensures request passes App Check
 */
const assertAppCheck: Middleware = (data, context, next) => {
  if (context.app === undefined)
    throw new HttpsError('failed-precondition', 'Failed App Check.');

  return next(data, context);
};

export default assertAppCheck;

断言已验证:

/**
 * Ensures user is authenticated
 */
const assertAuthenticated: Middleware = (data, context, next) => {
  if (!context.auth?.uid)
    throw new HttpsError('unauthenticated', 'Unauthorized.');

  return next(data, context);
};

export default assertAuthenticated;

作为奖励,这里有一个验证中间件,它使用 Joi 确保在调用处理程序之前验证数据:

const validateData: (schema: Joi.ObjectSchema<any>) => Middleware = (
  schema: Joi.ObjectSchema<any>,
) => {
  return (data, context, next) => {
    const validation = schema.validate(data);
    if (validation.error)
      throw new HttpsError(
        'invalid-argument',
        validation.error.message,
      );

    return next(data, context);
  };
};

export default validateData;

像这样使用验证中间件:

export const myCallableFunction = functions.https.onCall(
  withMiddlewares(
    [
      assertAuthenticated,
      validateData(
        Joi.object({
          name: Joi.string().required(),
          email: Joi.string().email().required(),
        }),
      ),
    ],
    async (data, context) => {
      // Your handler
    },
  ),
);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Firebase 可调用函数的中间件 的相关文章

随机推荐

  • ZF2:获取应用程序布局中的模块名称(或路由)以突出显示菜单

    如何在 ZF2 中获取应用程序布局中当前 选定的 模块名称 目的 我的应用程序布局包括zf2应用程序的主菜单 每次选择模块时我需要突出显示该模块的菜单语音 另外 当用它制作菜单时 我需要设置正确的路线 url action 每个模块都有菜单
  • OSX 上的 Java 文件限制低于 bash

    我增加了 macbook pro 上的最大文件限制 以便 Elasticsearch 可以处理更多文件 但它不起作用 我运行命令 ulimit a 它显示 打开文件 为 100 000 我可以运行一个简单的 shell 脚本 如下所示 ex
  • Ajax.Actionlink 在新页面中打开

    我有一个需要在两个 div 之间加载的部分视图 但是当调用 ajax actionlink 时 它会在新的浏览器窗口中打开部分视图中的内容 我使用 UpdateTargetId ajaxReplace Regards 您是否包含 引用了所有
  • 使用 Elasticsearch NEST C# 索引 Json 文档

    我对 Elasticsearch 很陌生 想知道如何使用 NEST C 创建索引以及将 json 文档索引到 Elasticsearch BookName Book1 ISBN 978 3 16 148410 0 chapter chapt
  • 如何停止 array.filter() 函数

    我正在使用自定义搜索过滤器 HtML
  • 序列化 MD5 计算状态并稍后恢复?

    我想序列化 反序列化 md5 上下文 但我不知道如何在Python中做到这一点 我想做的事情的伪代码 import md5 Start hash generation m md5 new m update Content Serialize
  • __next_prime 符号未定义

    我将 unordered map 包含在 iOS 的 XCode 项目中 最初 当我尝试链接时 我遇到了新建和删除操作的错误 但是当我将 lstdc 添加到 其他链接器标志 时 这些错误消失了 但我留下了以下缺失的符号 std 1 next
  • Spring Security CORS 过滤器不工作

    我将 spring security 与 OAuth2 版本 4 0 4 RELEASE 和 spring 版本 4 3 1 RELEASE 一起使用 我正在 Angular 中开发前端 并且正在使用 grunt connect dev h
  • 禁用 AJAX 缓存

    我现在有点进退两难 我正在构建一个将从 CGI 后端获取数据的网页 我无法控制 CGI 后端 也无法控制服务器 因此没有 mod headers 或 mod expires 另外 由于脚本的参数 我无法为每个请求附加唯一值 如 089u0a
  • 如何在express.js资产上设置响应标头

    我需要将 CORS 设置为在 Express 提供的脚本上启用 如何在这些返回的公共 资产响应中设置标头 npm 上至少有一个中间件用于处理 Express 中的 CORS cors 参见 mscdex 答案 这是设置自定义响应标头的方法
  • MySQL 可以拆分列吗?

    我有一列包含逗号分隔的数据 1 2 3 3 2 1 4 5 6 5 5 5 我正在尝试运行一个搜索来单独查询 CSV 字符串的每个值 0
  • 通过资源字体更改 PreferenceFragment 字体

    为了为 PreferenceFragment 中的每个 Preference 提供自定义字体 我必须为 Preference 编写一个新的自定义类each偏好类型 CustomSwitchPreference CustomEditTextP
  • 将 JSON 数组嵌套到 Python Pandas DataFrame

    我正在尝试扩展 pandas dataframe 中的嵌套 json 数组 这就是我的 JSON id 0001 name Stiven location country Colombia department Choc city Quib
  • Twitter Bootstrap Collapse Group 仅在手机上

    我有一个使用 Twitter Bootstrap 编写的网站 我在网站上有一组按钮 我想折叠这些按钮 但仅当在手机上查看该网站时才折叠 因此 当用户在计算机上查看该网站时 他们会看到所有按钮 但当他们在手机上时 他们只会看到一个按钮 上面写
  • 如何在 Protractor 中配置 Firefox 二进制文件位置?

    我成功地使用 Chrome 运行 Protractor 测试 并使用 Protractor 配置中的以下部分指定了 chrome 二进制文件的路径 capabilities You can use other browsers like f
  • 如何在没有引用的情况下复制反应中的状态? [复制]

    这个问题在这里已经有答案了 当我想像这样复制状态时 let copy this state foo copy push bar 状态复制正确 但有其参考 当我更改 复制 时 主状态会发生变化 我应该怎样做才能避免这种变化 您可以使用数组扩展
  • 所选类实例的 Swift 扩展

    在 Objective C 类别中 您可以通过在类中包含类别的标头来引入类别方法引入的扩展功能 似乎所有 Swift 扩展都是自动引入的 无需导入 如何在 Swift 中实现同样的目标 例如 extension UIView only wa
  • 跟踪 sitecore 中的 NullReferenceExceptions

    我正在尝试跟踪在加载任何网页时显示在 sitecore 6 5 上的 NullReferenceException NullReferenceException Object reference not set to an instance
  • Spark:重新分区与分区中列参数的顺序

    考虑的方法 Spark 2 2 1 DataFrame repartition 这两个实现需要partitionExprs Column 参数 DataFrameWriter partitionBy 注意 这个问题并没有问这些方法之间的区别
  • Firebase 可调用函数的中间件

    With Firebase HTTP 函数 我们可以安装express并使用中间件 中间件对于在函数执行之前检查先决条件非常有用 除其他外 例如 我们可以在中间件中检查身份验证 授权等 这样就不需要在每个端点定义中重复它们 开发人员如何实现