如何保护firebase云功能HTTP端点仅允许Firebase经过身份验证的用户?

spa*_*key 104 firebase firebase-security firebase-authentication firebase-realtime-database google-cloud-functions

使用新的firebase云功能,我决定将我的一些HTTP端点移动到firebase.一切都很好......但我有以下问题.我有两个端点由HTTP触发器(云功能)构建

  1. 用于创建用户并返回Firebase Admin SDK生成的自定义令牌的API端点.
  2. 用于获取特定用户详细信息的API端点.

虽然第一个端点很好,但对于我的第二个端点,我希望仅为经过身份验证的用户保护它.意思是拥有我之前生成的令牌的人.

我该如何解决这个问题?

我知道我们可以使用云函数获取Header参数

request.get('x-myheader')
Run Code Online (Sandbox Code Playgroud)

但有没有办法保护端点就像保护实时数据库一样?

Dou*_*son 103

您正在尝试执行的操作有一个官方代码示例.它说明了如何设置HTTPS功能以要求Authorization标头包含客户端在身份验证期间收到的令牌.该函数使用firebase-admin库来验证令牌.

此外,如果您的应用程序能够使用Firebase客户端库,您可以使用" 可调用函数 "使这个样板更容易.

  • 此代码示例仍然有效吗?这仍然是你今天解决这个问题的方式吗? (3认同)
  • @1252748 如果您阅读链接的文档,它就会变得清晰。它自动处理身份验证令牌的传递和验证,因此您不必在任一侧编写该代码。 (3认同)
  • 使用可调用函数如何使样板文件变得更容易?据我了解,这些只是“非 REST”服务器功能,我不太明白它们在这里有何关系。谢谢。 (2认同)
  • 我觉得这个例子很糟糕。为什么我想在函数中创建一个 Express 应用程序? (2认同)

Wil*_*ill 89

正如@Doug所提到的,您可以firebase-admin用来验证令牌.我已经建立了一个简单的例子:

exports.auth = functions.https.onRequest((req, res) => {
  cors(req, res, () => {
    const tokenId = req.get('Authorization').split('Bearer ')[1];

    return admin.auth().verifyIdToken(tokenId)
      .then((decoded) => res.status(200).send(decoded))
      .catch((err) => res.status(401).send(err));
  });
});
Run Code Online (Sandbox Code Playgroud)

在上面的例子中,我也启用了CORS,但这是可选的.首先,你得到Authorization标题并找出答案token.

然后,您可以firebase-admin用来验证该令牌.您将在响应中获得该用户的已解码信息.否则,如果令牌无效,则会抛出错误.

我希望它有所帮助.

  • Upvoted因为它很简单,并且不依赖于像官方例子那样的表达. (9认同)
  • 你能解释一下关于这些人的更多信息吗? (4认同)
  • @RezaRahmati您可以在客户端使用`getIdToken()`方法(例如firebase.auth()。currentUser.getIdToken()。then(token => console.log(token))`)[firebase docs]( https://firebase.google.com/docs/reference/js/firebase.User#getIdToken) (4认同)

Ben*_*nny 31

正如@Doug 也提到的,您可以使用Callable Functions来从客户端和服务器中排除一些样板代码

可调用函数示例:

export const getData = functions.https.onCall((data, context) => {
  // verify Firebase Auth ID token
  if (!context.auth) {
    return { message: 'Authentication Required!', code: 401 };
  }

  // do your things..
  const uid = context.auth.uid;
  const query = data.query;

  return { message: 'Some Data', code: 400 };
});
Run Code Online (Sandbox Code Playgroud)

它可以直接从您的客户端调用,如下所示:

firebase.functions().httpsCallable('getData')({query}).then(result => console.log(result));
Run Code Online (Sandbox Code Playgroud)


ult*_*tle 7

上述方法使用函数内部的逻辑对用户进行身份验证,因此仍必须调用该函数进行检查。

这是一个非常好的方法,但为了综合考虑,还有一个替代方案:

您可以将函数设置为“私有”,以便除注册用户外无法调用它(您决定权限)。在这种情况下,未经身份验证的请求会在函数上下文之外被拒绝,并且根本不会调用该函数。

以下是对 (a) 将函数配置为 public/private,然后 (b)验证最终用户对您的函数的引用。

请注意,上面的文档适用于 Google Cloud Platform,确实如此,因为每个 Firebase 项目也是一个 GCP 项目。与此方法相关的一个警告是,在撰写本文时,它仅适用于基于 Google 帐户的身份验证。