我有一个只有PHP(没有Java,没有node.js)的共享主机方案 . 我需要从我的Android应用程序发送firebase ID令牌并通过PHP-JWT验证它 .
我正在按照教程:Verify Firebase ID tokens
它说:
“如果您的后端使用的语言没有官方的Firebase Admin SDK,您仍然可以验证ID令牌 . 首先,找到适合您语言的第三方JWT库 . 然后,验证 Headers ,有效负载和签名ID令牌 . “
我发现那个库:Firebase-PHP-JWT . 在gitHub示例中;我无法理解
$关键部分:
`$key = "example_key";`
和
$ token部分:
`$token = array(
"iss" => "http://example.org",
"aud" => "http://example.com",
"iat" => 1356999524,
"nbf" => 1357000000
);`
我的问题:
-
$key 变量应该是什么?
-
为什么 &token 变量是一个数组?将从移动应用程序发送的令牌是一个字符串 .
-
如果有人可以发布用PHP-JWT验证firebase ID的完整示例,我将不胜感激 .
EDIT:
哦,我明白了 . GitHub示例演示了如何生成JWT代码(编码)以及如何解码它 . 在我的情况下,我只需要解码由firebase编码的jwt . 所以,我只需要使用这个代码:
$decoded = JWT::decode($jwt, $key, array('HS256'));
在此代码中, $jwt 是firebase ID令牌 . 对于 $key 变量文档说:
最后,确保ID令牌由与令牌的孩子声明相对应的私钥签名 . 从https://www.googleapis.com/robot/v1/metadata/x509/securetoken@system.gserviceaccount.com获取公钥,并使用JWT库验证签名 . 使用来自该 endpoints 的响应的Cache-Control标头中的max-age值来了解何时刷新公钥 .
I didn't understand how to pass this public keys to decode function. Keys are something like this:
“----- BEGIN CERTIFICATE ----- \ nMIIDHDCCAgSgAwIBAgIIZ36AHgMyvnQwDQYJKoZIhvcNAQEFBQAwMTEvMC0GA1UE \ nAxMmc2VjdXJldG9rZW4uc3lzdGVtLmdzZXJ2aWNlYWNjb3VudC5jb20wHhcNMTcw \ nMjA4MDA0NTI2WhcNMTcwMjExMDExNTI2WjAxMS8wLQYDVQQDEyZzZWN1cmV0b2tl \ nbi5zeXN0ZW0uZ3NlcnZpY2VhY2NvdW50LmNvbTCCASIwDQYJKoZIhvcNAQEBBQAD \ nggEPADCCAQoCggEBANBNTpiQplOYizNeLbs r941T392wiuMWr1gSJEVykFyj7fe \ nCCIhS / zrmG9jxVMK905KwceO / FNB4SK l8GYLb559xZeJ6MFJ7QmRfL7Fjkq7GHS \ N0 / sOFpjX7vfKjxH5oT65Fb1 Hb4RzdoAjx0zRHkDIHIMiRzV0nYleplqLJXOAc6E \ n5HQros8iLdf ASdqaN0hS0nU5aa / CPU / EHQwfbEgYraZLyn5NtH8SPKIwZIeM7Fr \ NNH SS7JSadsqifrUBRtb // fueZ / FYlWqHEppsuIkbtaQmTjRycg35qpVSEACHkKc \ nW05rRsSvz7q1Hucw6Kx / dNBBbkyHrR4Mc / wg31kCAwEAAaM4MDYwDAYDVR0TAQH / \ nBAIwADAOBgNVHQ8BAf8EBAMCB4AwFgYDVR0lAQH / BAwwCgYIKwYBBQUHAwIwDQYJ \ nKoZIhvcNAQEFBQADggEBAEuYEtvmZ4uReMQhE3P0iI4wkB36kWBe1mZZAwLA5A U \ niEODMVKaaCGqZXrJTRhvEa20KRFrfuGQO7U3FgOMyWmX3drl40cNZNb3Ry8rsuVi \ nR1dxy6HpC39zba / DsgL07enZPMDksLRNv0dVZ / X / wMrTLrwwrglpCBYUlxGT9RrU \ nf8nAwLr1E4EpXxOVDXAX8bNBl3TCb2fu6DT62ZSmlJV4 0K wTRUlCqIewzJ0wMt6 \ nO8 6kVdgZH4iKLi8gVjdcFfNsEpbOBoZqjipJ63l4A3mfxOkma0d2XgKR12KAfYX \ ncAVPgihAPoNoUPJK0Nj CmvNlUBXCrl9TtqGjK7AKi8 = \ n ----- END CERTIFICATE ----- \ n“
我是否需要在传递之前将此公钥转换为某些内容?我试图删除所有 "\n" 和 "-----BEGIN CERTIFICATE-----" , "-----BEGIN CERTIFICATE-----" ......但没有运气 . 我仍然得到无效的签名错误 . 有什么建议?
3 回答
仅当您使用密码对令牌进行签名时才使用HS256 . Firebase在发出令牌时使用RS256,因此,您需要来自给定URL的公钥,并且您需要将算法设置为RS256 .
另请注意,您在应用程序中获得的令牌不应该是一个数组,而是一个包含3个部分的字符串:
header
,body
和signature
. 每个部分由.
分隔,因此它为您提供了一个简单的字符串:header.body.signature
为了验证令牌,您需要做的是定期从given URL下载公钥(检查该信息的
Cache-Control
Headers )并将其保存(JSON)在文件中,这样您就不必每次都检索它你需要检查JWT的时间 . 然后,您可以读入文件并解码JSON . 解码后的对象可以传递给JWT::decode(...)
函数 . 这是一个简短的样本:现在
$decoded
变量包含令牌的有效负载 . 获得解码后的对象后,仍需要进行验证 . 根据ID令牌验证的the guide,您必须检查以下内容:exp
将来iat
已过去iss
:https://securetoken.google.com/<firebaseProjectID>
aud
:<firebaseProjectID>
sub
非空因此,例如,您可以像这样检查
iss
(其中FIREBASE_APP_ID
是来自firebase控制台的应用程序ID):以下是刷新密钥和检索密钥的完整示例 .
最好的事情是安排一个cronjob在需要时调用
checkKeys()
,但我不知道你的提供者是否允许这样做 . 而不是那样,你可以为每个请求执行此操作:接受答案的工作实例 . 注意差异:
经过测试和工作
适用于非类环境
更多代码显示如何将其用于Firebase(简单,单行发送验证代码)
UnexpectedValueException涵盖了您可能看到的各种错误(例如过期/无效密钥)
评论很好且易于理解
从Firebase令牌返回一系列VERIFIED数据(您可以安全地将此数据用于您需要的任何内容)
这基本上是一个破碎的,易于阅读/理解的PHP版本https://firebase.google.com/docs/auth/admin/verify-id-tokens
注意:您可以使用getKeys(),refreshKeys(),checkKeys()函数生成用于任何安全api情况的密钥(使用您自己的模拟“verify_firebase_token”函数的功能) .
使用:
代码:
您可以查看此库,而不是手动完成所有操作:
Firebase Tokens甚至Firebase Admin SDK for PHP . 缓存内容已经实现,只需看看文档即可 .
基本上,您只需使用Firebase令牌库执行以下操作: