Firebase 3中是否还可以对令牌进行服务器端validation?

Firebase 3中是否还可以对令牌进行服务器端validation?

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

FIRAuth.auth()?.signInWithCustomToken(customToken) 

直到那里一切正常。 但是,当我们将客户端令牌传递给从

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

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

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

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

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

新的SDK版本比较强大,而且我们对这个function的总结还没有做的很好。 这似乎是一个比较可用的工具和它们的用途的好地方,然后我将在最后讨论一些第三方(即Go)的特定笔记。

使用外部validation工具进行客户端validation

minting自定义令牌的主要用途是允许用户根据您所控制的外部/传统授权机制(例如LDAP服务器)进行身份validation。 这里介绍的基本过程如下: iOS , Android , Web 。

本质上,您的服务只是将JWT令牌提供给客户端。 客户端使用您提供的自定义令牌进行validation/validation。

validation你的特权员工

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

然后,通过使用firebase.initializeApp()serviceAccount属性引用该JSON来包含您的服务帐户凭据,并且您在! 这是在这里logging ,看起来像这样(请参阅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" }); 

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

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

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

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

通过安全validation客户身份

首先,如果您正在使用Firebase数据库,通常可以避免处理服务器端validation,方法是让客户端写入数据库并使用安全规则validation其身份。 如果您的服务器在需要validation的path上进行侦听,那么在服务器上没有任何特殊的安全性就已经解决了。

通过将其build模为事件队列,它创build了一个简单的,模块化的,可扩展的服务器工作者策略。 看到firebase队列的一些伟大的Node.js工具。 它支持3.x。

validation服务器上的客户端标识令牌

如果您没有使用实时数据库并需要接收客户端令牌(例如,通过REST调用)并validation它们是否有效,那么可以使用verifyIdToken()来执行此操作 。 这看起来像下面这样:

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

如果您希望以该用户身份进行身份validation以写入数据库并强制执行安全性,则可以使用上面的仿真用户部分。 换句话说,用databaseAuthVariableOverride调用initializeApp()设置为合适的uid。

请注意,如果您尝试多次调用initializeApp()并运行类似如下的Error: Firebase App named '[DEFAULT]' already exists. 您可以通过向initializeApp()调用(例如database.initializeApp({...}, 'asUser'+uid) )添加第二个参数来初始化多个应用上下文,然后使用firebase.database('asUser'+uid) .ref(…)。 要详细了解如何使用多个应用程序实例, 请看这里 。

Java代码在上面的链接中可用。 Go和其他第三方解决scheme如下。

创build用于REST API的令牌

Michael Bleigh 在这里介绍了这种情况,值得一些代表工作。

创build令牌或通过RESTvalidation它们

这不被支持。 抱歉。

Golang和其他人:更多来

我们正在开发一个Go令牌pipe理和validation库。 我们也会很快joinPython工具。 没有发布date或ballparks为此。 与此同时,如果您不想使用官方Firebase Node.js或Java库(内置validation方法)来validation客户端标识令牌,则需要确保标识令牌(这是JWT)符合以下内容:

  • 其解码的头部具有等于"RS256"alg (algorithm)声明。
  • 其解码的有效负载具有等于您的Firebase项目ID的aud (受众)声明。
  • 其解码的有效负载具有相当于"https://securetoken.google.com/<projectId>"iss (发行者)声明。
  • 其解码的有效负载有一个非空的stringsub (主题)声明。 请注意,这是该Firebase用户的uid
  • 其解码的标头包含一个与https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com列出的公钥之一的kid (密钥ID)声明。
  • 您还需要使用JWT库来validation具有公钥的令牌,以certificate令牌是使用公钥的相应私钥进行签名的。

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

那么firebase不允许validationcustom tokens ,他们所做的就是允许validation用户使用自定义令牌login后生成的令牌。 就像我一样,如果您将Firebase自定义令牌传递给其他服务以与您的后端进行身份validation,那么您的自定义令牌validation就会出现在您的身上! 此外,谷歌服务帐户X509 cert格式不正确。 它有这些\n (new line)分隔符不会被文本编辑器中的新行代替(我使用vim )。 所以我做的是这样的:

  val factory = CertificateFactory.getInstance("X.509") val certificateFile = this.getClass.getResourceAsStream(Play.current.configuration.getString("firebase.certificate").get) val publicKey = factory.generateCertificate(certificateFile).asInstanceOf[X509Certificate].getPublicKey val claimBody = Jwts.parser().setSigningKey(publicKey).parseClaimsJws(compactJws).getBody 
  1. 从设置Firebase时下载的json中指定的Google服务帐户链接获取证书
  2. 用新行手动replace\n
  3. 获取智威汤逊图书馆。 我用这个伟大的库来validationJava JWT
  4. 阅读证书并提取出公钥。
  5. 使用公钥来validation令牌
  6. 确保你有另一个API刷新令牌,因为只有一个小时有效

希望有所帮助!