【问题标题】:Firebase REST access using PHP with Authentication使用带有身份验证的 PHP 进行 Firebase REST 访问
【发布时间】:2016-10-26 11:10:03
【问题描述】:

我正在尝试从使用 PHP、Google Auth library 和用于 Firebase REST 的 wrapper 的服务器访问 Firebase...这非常适合实现这一目标:

use Firebase\JWT\JWT;
use Google\Auth\Credentials\ServiceAccountCredentials;
use Google\Auth\HttpHandler\HttpHandlerFactory;
use GuzzleHttp\Client;

$email = 'account@email.com';
$key = 'private_key_goes_here';

$scopes = [
    'https://www.googleapis.com/auth/userinfo.email',
    'https://www.googleapis.com/auth/firebase.database',
];

$creds = [
    'client_email' => $email,
    'private_key' => $key,
];

$serviceAccount = new ServiceAccountCredentials($scopes, $creds);
$handler = HttpHandlerFactory::build(new Client());
$token = $serviceAccount->fetchAuthToken($handler);

$firebase = new \Firebase\FirebaseLib($url, $token);
$value = $firebase->get('test/hello');
# $value now stores "world"

但是,这需要 Firebase 中的安全规则是通用读/写,这是我不想要的。如果我将我的安全规则更新为:

{
  "rules": {
    "test": {
      ".read": "auth != null"
    }
  }
}

$value 中的结果变为{"error": "Permission denied"}。我进行了广泛的搜索,并尝试了许多排列和可能的解决方案,但没有确凿的结果。

我已经使用this code 向最终客户端提供 JWT 令牌,它们可以成功使用它们并毫无问题地利用安全规则。我最初为服务器尝试了相同的方法,但没有成功。我选择尝试结合这两种方法:

# Snipping code that didn't change...
$serviceAccount = new ServiceAccountCredentials($scopes, $creds);
$handler = HttpHandlerFactory::build(new Client());

$payload = [
    'iss' => $email,
    'sub' => $email,
    'aud' => 'https://identitytoolkit.googleapis.com/google.identity.identitytoolkit.v1.IdentityToolkit',
    'iat' => time(),
    'exp' => time() + 60 * 60,
    'uid' => '123',
    'claims' => [
        'uid' => '123',
    ],
];

$payload = $serviceAccount->updateMetadata($payload);
$token = JWT::encode($payload, $key, 'RS256');

$firebase = new \Firebase\FirebaseLib($url, $token);
$value = $firebase->get('test/hello');

这似乎接近了,但$value 现在包含{"error": "Missing claim 'kid' in auth header."}。为了解决这个问题,我修改了编码调用:

$token = JWT::encode($payload, $key, 'RS256', 'key_id_goes_here');

这会导致稍有不同的错误:Invalid claim 'kid' in auth header.,表明我在正确的轨道上......但并不完全在那里。直接使用 JWT 令牌会产生完全相同的结果。任何想法我做错了什么?电子邮件、私钥和密钥 ID 都直接来自我创建服务帐户时提供的 json 凭据文件。

我查看了几十页的文档和帖子,以下是最有帮助的:

发帖到Firebase Google Group

【问题讨论】:

    标签: php rest firebase firebase-realtime-database firebase-authentication


    【解决方案1】:

    最终,我最终使用的解决方案是切换 PHP 库。我最初驳回了this library,因为它正在转向仅支持 PHP7,我还没有准备好迁移到它,但当前版本 (1.1) 运行良好:

    use Kreait\Firebase\Configuration;
    use Kreait\Firebase\Firebase;
    
    $clientId = '1234567890';
    $email = 'account@email.com';
    $key = 'private_key_goes_here';
    $url = 'https://example.firebaseio.com';
    
    $fbConfig = new Configuration();
    $fbConfig->setAuthConfigFile([
        'type' => 'service_account',
        'client_id' => $clientId,
        'client_email' => $email,
        'private_key' => $key,
    ]);
    
    $fb = new Firebase($url, $fbConfig);
    $value = $fb->get('test/hello');
    # $value now stores "world"
    

    【讨论】:

    • 您好,能否提供您的演示源代码?我还需要使用 php 来使用 firebase。请给demo源码谢谢
    【解决方案2】:

    您可以在使用将成为安全规则中的auth 变量的服务帐户进行身份验证时指定auth_variable_override 查询参数。它应该是一个正确转义的 JSON 对象。例如要执行{"uid":123},您需要添加:

    ?auth_variable_override=%7B%22uid%22%3A%22123%22%7D
    

    到您的请求 URL 的末尾。

    【讨论】:

    • 感谢您的回复。 PHP 库有一个用于构建查询字符串的选项参数。我试过这个(和许多其他排列):$value = $firebase->get('test/hello', ['auth_variable_override' => ['uid' => 123]]); ...但无济于事,我仍然收到拒绝的许可。我确认 lib 使用的 url 是 https://sample-db.firebaseio.com/test.json?auth_variable_override=%7B%22uid%22%3A%22123%22%7D&auth%5Baccess_token%5D=token_here&auth%5Btoken_type%5D=Bearer&auth%5Bexpires_in%5D=3600 ....我错过了什么?
    猜你喜欢
    • 1970-01-01
    • 2018-09-11
    • 2017-04-11
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-10-09
    • 2017-03-11
    相关资源
    最近更新 更多