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

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

问题描述

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

在Firebase 3中是否可以对令牌进行服务器端验证? (使用服务帐户)。
令牌在iOS客户端上使用

  FIRAuth.auth()?。signInWithCustomToken(customToken)

直到那里一切正常。但是,当我们将客户机令牌传递给从以下服务器获取的服务器:

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

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



我知道可以使用Java或Javascript中的verifyIdToken调用来验证客户令牌,但是我们希望能够在Golang中使用标准的JWT库来实现这一点。



在Firebase 2(使用HS256和Firebase秘密)中, / p>

解决方案

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

新的SDK版本比较强大,而且我们还没有做出很好的总结功能。这似乎是一个很好的对比工具和他们的使用的地方,然后我会在最后的一些第三方(即去)特定的笔记。



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

使用自定义令牌的主要用途是允许用户使用外部/传统身份验证您控制的机制,例如您的LDAP服务器。这里介绍的基本过程如下: iOS Android Web

实际上,你的服务只是提供JWT令牌,并把它传递给客户端。客户使用您提供的自定义令牌进行验证/验证。

对特权员工进行身份验证



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

然后,通过使用<$ c引用该JSON来包含您的服务帐户凭据code> serviceAccount 属性放在 firebase.initializeApp()中,你就在!这是记录在这里,看起来像这样(见链接为Java版本):

  var firebase = require(firebase); 

//使用服务帐户初始化应用,授予管理员权限
firebase.initializeApp({
databaseURL:https://databaseName.firebaseio.com,
serviceAccount:./serviceAccountCredentials.json
});

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



模拟用户或限制从服务器进程访问(强烈推荐)是相当简单的。你真的不需要再为此定制一个自定义标记了。

这只需要添加 databaseAuthVariableOverride 到您调用 database.initializeApp()
$ b

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

通过安全验证客户身份
$ b

首先,如果您使用Firebase数据库,通常可以避免处理服务器端验证,方法是让客户端写入数据库并使用安全规则验证其身份。如果你的服务器在一个需要认证的路径上进行侦听,那么这已经被解决了,而服务器没有任何特殊的安全性。
$ b 通过建立这个事件队列,它创建了一个简单,模块化和可扩展的服务器工作者策略。请参阅 firebase-queue ,了解一些优秀的Node.js工具。它支持3.x



验证服务器上的客户端标识符



如果您不使用实时数据库并需要接收客户端令牌通过REST调用),并验证它们是有效的,您可以通过使用 verifyIdToken()来实现,如这里。这看起来像下面这样:

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

如果您想以该用户的身份进行身份验证以写入数据库并强制执行安全性,则可以使用上面的用户部分。换句话说,用 databaseAuthVariableOverride 调用 initializeApp()来设置适当的uid。 b

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



上面的链接提供了Java代码。 Go和其他第三方解决方案。



创建用于REST API的令牌



Michael Bleigh报道了这种情况这里,值得一些rep工作。

创建令牌或通过REST验证



这不支持。对不起。



Golang和其他人:更多来

在一个去令牌minting和验证库。我们也会很快加入Python工具。没有发布日期或ballparks为此。与此同时,如果您不想使用官方Firebase Node.js或Java库(内置验证方法)来验证客户端标识令牌,则需要确保标识令牌(这是JWT)符合以下内容:


  • 它的解码头有一个 alg 等于RS256

  • 其解码的有效载荷有一个 aud 您的Firebase项目ID。
  • 其解码的有效负载具有 iss (发行者)等于https://securetoken.google.com/<projectId>

  • 解码的有效内容有一个非空字符串 sub (subject)声明。请注意,这是该Firebase用户的 uid
  • 其解码的标头包含 kid (密钥ID)声明对应于 https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com中列出的公钥之一
  • 您还需要使用JWT库来验证具有公钥的令牌,以证明令牌是使用公钥对应的私钥进行签名的。



对于Go,看起来您可以使用 jwt-go 解码并验证客户端ID令牌。


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

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 ..})

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?

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.

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.

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.

Using an external authentication tool for client authentication

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.

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.

Authenticating your privileged workers

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.

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"
});

Emulating users or limiting access from a server process

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.

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"
  }
});

Validating client identity via security

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.

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.

Verifying client ID tokens on the server

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;
});

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.

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 code available at the links above. Go and other third party solutions covered below.

Creating a token for use in the REST API

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

Creating tokens or verifying them via REST

This isn't supported. Sorry.

Golang and others: More to come

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:

  • 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.

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

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

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