firebase - 是否仍然可以在 Firebase 3 中对 token 进行服务器端验证?

标签 firebase firebase-authentication

是否仍然可以在 Firebase 3 中对 token 进行服务器端验证?

我们使用现有的身份验证系统(使用服务帐户)在运行 Golang 的服务器上生成自定义 token (JWT)。
该 token 在 iOS 客户端上使用

FIRAuth.auth()?.signInWithCustomToken(customToken)

直到那里一切正常。但是当我们将客户端 token 传递给从以下位置检索的服务器时:
FIRUser.getTokenWithCompletion({ token, error in ..})

我们无法验证它。 JWT token 是使用 RS256 签名的,并且有一个我们无法识别的 header.kid。来自服务帐户的公钥(用于签署自定义 token )不会验证客户端 token 。
验证客户端 token 所需的公钥是否可用?

我知道可以使用 Java 或 Javascript 中的“verifyIdToken”调用来验证客户端 token ,但我们希望仍然能够使用标准的 JWT 库在 Golang 中执行此操作。

这一切在 Firebase 2 中都运行良好(使用 HS256 和 Firebase secret)。

最佳答案

简短的回答是肯定的。完整的答案是,在大多数情况下,我们现在拥有更合适的工具。因此,很大程度上取决于您尝试解决的用例。

新的 SDK 版本功能要强大一些,我们还没有很好地总结功能。这似乎是对比可用工具及其用途的好地方,然后我将在最后添加一些第三方(即 Go)的特定注释。

使用外部身份验证工具进行客户端身份验证

类型转换自定义 token 的主要用途是允许用户根据您控制的外部/传统身份验证机制进行身份验证,例如您的 LDAP 服务器。此处介绍了此操作的基本过程:iOS , Android , Web .

本质上,您的服务只是创建 JWT token 并将其传递给客户端。客户端使用您提供的自定义 token 进行验证/身份验证。

验证您的特权 worker

不再需要使用自定义 token 来验证您的服务器进程。这是通过创建服务帐户来完成的,在 Adding Firebase to your Server 中逐步介绍了该帐户。 .完成后,您将得到一个包含私钥的 JSON 文件。

然后,您通过使用 serviceAccount 引用该 JSON 来包含您的服务帐户凭据。 firebase.initializeApp() 中的属性,你就进去了!已记录在案 here看起来像这样(请参阅 Java 版本的链接):

var firebase = require("firebase");

// Initialize the app with a service account, granting admin privileges
firebase.initializeApp({
  databaseURL: "https://databaseName.firebaseio.com",
  serviceAccount: "./serviceAccountCredentials.json"
});

模拟用户或限制来自服务器进程的访问

模拟用户或限制来自服务器进程的访问(强烈推荐)是相当简单的。您真的不再需要为此创建自定义 token 。

这只需添加 databaseAuthVariableOverride拨打您的电话 database.initializeApp() :
firebase.initializeApp({
  databaseURL: "https://databaseName.firebaseio.com",
  serviceAccount: "./serviceAccountCredentials.json",
  databaseAuthVariableOverride: {
    uid: "my-service-worker-or-user-uid"
  }
});

通过安全验证客户端身份

首先,如果您使用 Firebase 数据库,通常可以避免处理服务器端验证,方法是让您的客户端写入数据库并使用安全规则来验证其身份。如果您的服务器监听需要身份验证才能写入的路径,那么这已经在服务器上没有任何特殊安全性的情况下解决了。

通过将其建模为事件队列,它创建了一个简单、模块化和可扩展的服务器 worker 策略。见 firebase-queue一些很棒的 Node.js 工具。它supports 3.x .

验证服务器上的客户端 ID token

如果您没有使用实时数据库并且需要接收客户端 token (例如通过 REST 调用)并验证它们是否有效,您可以使用 verifyIdToken() 来实现。如所述 here .这将如下所示:
auth.verifyIdToken(idToken).then(function(decodedToken) {
  var uid = decodedToken.sub;
});

如果您随后想要以该用户身份进行身份验证以写入数据库并强制实现安全性,您将使用上面的模拟用户部分。换句话说,拨打 initializeApp()databaseAuthVariableOverride设置为适当的uid。

请注意,如果您尝试拨打 initializeApp()多次并遇到类似于以下的错误:Error: Firebase App named '[DEFAULT]' already exists.您可以通过向 initializeApp() 调用(例如 database.initializeApp({...}, 'asUser'+uid) )添加第二个参数来初始化多个应用程序上下文,然后使用 firebase.database('asUser'+uid) 引用该应用程序实例.ref(...)要阅读有关使用多个应用程序实例的更多信息,look here .

Java 代码可在上面的链接中找到。 Go 和下面介绍的其他第三方解决方案。

创建用于 REST API 的 token

Michael Bleigh 介绍了这种情况 here并且值得一些代表来解决这个问题。

创建 token 或通过 REST 验证它们

这不受支持。对不起。

Golang 和其他人:更多内容

我们正在开发一个 Go token 类型转换和验证库。我们也将很快为此添加 Python 工具。没有发布日期或球场。同时,如果您想在不使用官方 Firebase Node.js 或 Java 库(具有内置验证方法)的情况下验证客户端 ID token ,则需要确保 ID token (这是一个 JWT)符合以下规定:
  • 它的解码头有一个 alg (算法) claim 等于 "RS256" .
  • 它的解码有效载荷有一个 aud (受众)声明等于您的 Firebase 项目 ID。
  • 它的解码有效载荷有一个 iss (发行人) claim 等于 "https://securetoken.google.com/<projectId>" .
  • 它的解码有效载荷有一个非空字符串 sub (主题) claim 。请注意,这是 uid对于该 Firebase 用户。
  • 它的解码头有一个 kid (key ID) 声明对应于 https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com 中列出的公钥之一.
  • 您还需要使用 JWT 库来验证带有公钥的 token ,以证明 token 是使用公钥对应的私钥签名的。

  • 对于 Go,您似乎可以使用 jwt-go 解码和验证客户端 ID token 。

    关于firebase - 是否仍然可以在 Firebase 3 中对 token 进行服务器端验证?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37408684/

    相关文章:

    java - 如何从 Firebase 获取启用的登录方法?

    javascript - 通过 Angular 在 firebase 中使用自定义标题而不是 ID 创建新项目

    android - 是否有代码可以知道 firebase 数据库数据是否已加载?

    ios - 接收带有查询和键范围的项目

    swift - 密码重置 swift 4 firebase

    java - Firebase AuthUI - 未知错误代码

    java - Firebase_Auth_API 在 API 23 上不可用

    javascript - Firebase 部署 : Missing expected firebase config value databaseURL

    android - Firebase 用户属性 bool 值。 (对或错)

    firebase - 构建 apk 文件后 Flutter/Firebase Google 登录不起作用