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
(发行者)声明。 - 其解码的有效负载有一个非空的string
sub
(主题)声明。 请注意,这是该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
- 从设置Firebase时下载的json中指定的Google服务帐户链接获取证书
- 用新行手动replace
\n
- 获取智威汤逊图书馆。 我用这个伟大的库来validationJava JWT
- 阅读证书并提取出公钥。
- 使用公钥来validation令牌
- 确保你有另一个API刷新令牌,因为只有一个小时有效
希望有所帮助!