是否仍然可以在 Firebase 3 中对令牌进行服务器端验证? [英] Is it still possible to do server side verification of tokens in Firebase 3?

查看:16
本文介绍了是否仍然可以在 Firebase 3 中对令牌进行服务器端验证?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Is it still possible to do server side verification of tokens in Firebase 3?

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

We generate custom tokens (JWT) on a server running Golang using our existing authentication system (using a Service Account). The token is used on an iOS client using

FIRAuth.auth()?.signInWithCustomToken(customToken)

直到那里一切正常.但是当我们将客户端令牌传递给从以下位置检索到的服务器时:

Until there it all works fine. But when we pass the client token to the server retrieved from:

FIRUser.getTokenWithCompletion({ token, error in ..})

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

we're not able to verify it. The JWT token is signed using RS256 and has an header.kid we can't recognize. The public key from the Service Account (which was used to sign the custom token) doesn't verify the client token. Is the public key needed to validate the client token available?

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

I know it's possible to validate client tokens using the "verifyIdToken" call in Java or Javascript, but we hope to stil be able to do this in Golang using a standard JWT library.

这一切在 Firebase 2 中都运行良好(使用 HS256 和 Firebase 密钥).

This all worked fine in Firebase 2 (using HS256 and the Firebase secret).

推荐答案

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

The short answer is yes. The full answer is that, in most cases, we have a more appropriate tool now. So a lot depends on the use case you are trying to resolve.

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

The new SDK version is quite a bit more powerful, and we haven't done a great job of summarizing the capabilities. This seems like a good place to contrast the tools available and their uses, and then I'll tack on some third-party (i.e. Go) specific notes at the end.

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

创建自定义令牌的主要用途是允许用户根据您控制的外部/传统身份验证机制(例如您的 LDAP 服务器)进行身份验证.此处介绍了此操作的基本过程:iOSAndroidWeb.

The primary use of minting custom tokens is to allow users to authenticate against an external/legacy auth mechanism you control, such as your LDAP server. The basic process for this is covered here: iOS, Android, Web.

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

Essentially, your service just mints the JWT token and passes this to the client. The client does the verification/authentication using the custom token you provide.

验证您的特权工作者

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

It's no longer necessary to use custom tokens to authenticate your server process. This is done by creating a service account, which is covered step-by-step in Adding Firebase to your Server. When done, you'll end up with a JSON file that contains a private key.

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

Then, you include your service account credentials by referencing that JSON using the serviceAccount attribute in firebase.initializeApp(), and you're in! That's documented here and looks like this (see link for Java version):

var firebase = require("firebase");

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

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

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

It's fairly trivial to emulate a user or to limit access (highly recommended) from a server process. You don't really need to mint a custom token for this anymore.

这只需要将 databaseAuthVariableOverride 添加到您对 database.initializeApp() 的调用中:

This just requires adding the databaseAuthVariableOverride into your call to database.initializeApp():

firebase.initializeApp({
  databaseURL: "https://databaseName.firebaseio.com",
  serviceAccount: "./serviceAccountCredentials.json",
  databaseAuthVariableOverride: {
    uid: "my-service-worker-or-user-uid"
  }
});

通过安全验证客户端身份

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

First of all, you can usually avoid dealing with server-side verification if you are using Firebase Database, by having your client write to the database and using security rules to validate their identity. If your server listens on a path that requires authentication to write into, then this is already solved without any special security at the server.

通过将其建模为事件队列,它创建了一个简单、模块化且可扩展的服务器工作者策略.请参阅 firebase-queue 了解一些出色的 Node.js 工具.它支持 3.x.

By modeling this as an event queue, it creates a simple, modular, and scalable server worker strategy. See firebase-queue for some great Node.js tools. It supports 3.x.

验证服务器上的客户端 ID 令牌

如果您不使用实时数据库并且需要接收客户端令牌(例如通过 REST 调用)并验证它们是否有效,您可以使用 verifyIdToken() 如所述此处.这将如下所示:

If you aren't using the Realtime Database and need to receive client tokens (e.g. via REST calls) and verify that they are valid, you can do so by using verifyIdToken() as described here. This would look like the following:

auth.verifyIdToken(idToken).then(function(decodedToken) {
  var uid = decodedToken.sub;
});

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

If you then want to authenticate as that user to write to the database and enforce security, you would use the Emulating Users section above. In other words, call initializeApp() with a databaseAuthVariableOverride set to the appropriate uid.

请注意,如果您尝试多次调用 initializeApp() 并遇到类似于以下内容的错误:错误:名为[DEFAULT]"的 Firebase 应用程序已经存在. 您可以通过向 initializeApp() 调用(例如 database.initializeApp({...}, 'asUser'+uid))添加第二个参数来初始化多个应用程序上下文,然后引用它使用 firebase.database('asUser'+uid).ref(...) 的应用实例.要详细了解如何使用多个应用实例,请查看此处.

Note that, if you try to call initializeApp() multiple times and run into an error similar to the following: Error: Firebase App named '[DEFAULT]' already exists. You can initialize multiple app contexts by adding a second argument to the initializeApp() call (e.g. database.initializeApp({...}, 'asUser'+uid)) and then reference that app instance by using firebase.database('asUser'+uid).ref(...). To read more on using multiple app instances, look here.

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

Java code available at the links above. Go and other third party solutions covered below.

创建用于 REST API 的令牌

Michael Bleigh 介绍了这个场景 这里 并且值得一些代表来解决这个问题.

Michael Bleigh covered this scenario here and deserves some rep for working this out.

创建令牌或通过 REST 验证它们

这不受支持.对不起.

Golang 和其他人:更多内容

我们正在开发 Go 令牌铸造和验证库.我们也将很快为此添加 Python 工具.没有发布日期或球场.同时,如果您想在不使用官方 Firebase Node.js 或 Java 库(具有内置验证方法)的情况下验证客户端 ID 令牌,则需要确保 ID 令牌(这是一个 JWT)符合以下条件:

We're working on a Go token minting and verification library. We'll also be adding Python tools for this soon as well. No release date or ballparks for this. In the mean time, if you'd like to verify client ID tokens without using the official Firebase Node.js or Java libraries (which have built-in verification methods), you will need to ensure the ID token (which is a JWT) conforms to the following:

  • 它的解码头有一个 alg(算法)声明等于 "RS256".
  • 其解码的有效负载具有与您的 Firebase 项目 ID 相同的 aud(受众)声明.
  • 其解码的有效负载具有 iss(颁发者)声明,等于 "https://securetoken.google.com/".
  • 其解码的有效负载具有非空字符串 sub(主题)声明.请注意,这是该 Firebase 用户的 uid.
  • 其解码的标头具有 kid(密钥 ID)声明,该声明对应于 https://www.googleapis.com/robot/v1/metadata/中列出的公钥之一x509/securetoken@system.gserviceaccount.com.
  • 您还需要使用 JWT 库通过公钥验证令牌,以证明令牌是使用公钥对应的私钥签名的.
  • Its decoded header has an alg (algorithm) claim equal to "RS256".
  • Its decoded payload has an aud (audience) claim equal to your Firebase project ID.
  • Its decoded payload has an iss (issuer) claim equal to "https://securetoken.google.com/<projectId>".
  • Its decoded payload has a non-empty string sub (subject) claim. Note that this is the uid for that Firebase user.
  • Its decoded header has a kid (key ID) claim that corresponds to one of the public keys listed at https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com.
  • You also need to use a JWT library to verify the token with the public key to prove the token was signed with the public keys' corresponding private key.

对于 Go,您似乎可以使用 jwt-go 解码和验证客户端 ID 令牌.

For Go, it looks like you can use jwt-go to decode and validate the client ID token.

这篇关于是否仍然可以在 Firebase 3 中对令牌进行服务器端验证?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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