Firebase REST-доступ с использованием PHP с аутентификацией

Я пытаюсь получить доступ к Firebase с сервера, используя PHP, Библиотека Google Auth, и обертка для REST Firebase … Это прекрасно работает, чтобы сделать это:

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

$email = '[email protected]';
$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"}, Я много искал и пробовал многочисленные перестановки и возможные решения без каких-либо окончательных результатов.

Я использовал этот код предоставлять токены 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 напрямую дает те же самые результаты. Есть идеи, что я делаю не так? Электронная почта, закрытый ключ и идентификатор ключа пришли прямо из json Файл учетных данных предоставляется при создании учетной записи службы.

Я просмотрел десятки страниц документации и постов, вот те, которые были самыми полезными:

Крест размещен на Firebase Google Group.

4

Решение

Вы можете указать auth_variable_override параметр запроса при аутентификации с помощью учетной записи службы, которая станет auth переменная в правилах безопасности. Это должен быть правильно экранированный объект JSON. Например сделать {"uid":123} Вы хотели бы добавить:

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

в конце вашего запроса URL.

2

Другие решения

В конечном итоге, решение, которое я выбрал, заключалось в переключении библиотек PHP. Я изначально уволил эта библиотека потому что он движется к поддержке только PHP7, к которой я еще не готов перейти, но текущая версия (1.1) работала нормально:

use Kreait\Firebase\Configuration;
use Kreait\Firebase\Firebase;

$clientId = '1234567890';
$email = '[email protected]';
$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"
1

По вопросам рекламы [email protected]