Firebase可调用函数的中间件 [英] Middleware for Firebase Callable Functions

查看:21
本文介绍了Firebase可调用函数的中间件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

通过Firebase HTTP functions,我们可以安装Express和使用中间件。中间件对于在函数执行之前检查前提条件非常有用(尤其如此)。例如,我们可以在中间件中检查身份验证、授权等,这样就不需要在每个端点定义中重复它们。

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

推荐答案

似乎没有现成的可调用函数的中间件框架,因此受this的启发,我推出了自己的中间件框架。NPM上有一些通用的链式中间件框架,但我需要的中间件是如此简单,以至于我自己滚动比配置一个库来处理可调用的函数要容易得多。

可选:如果您使用的是TypeScrip:

,则为中间件声明类型
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,只有在它们都通过之后,才会调用您的处理程序。

这两个中间件是:

assertAppCheck:

/**
 * 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
    },
  ),
);

这篇关于Firebase可调用函数的中间件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆