Простое (и) грязное правило аутентификации Firestore - PullRequest
0 голосов
/ 21 февраля 2019

Я использую REST API в проекте PHP для отправки данных в Firestore DB через curl (PHP curl).

Я пытаюсь понять, как настроить правило аутентификации для "службы"и предложенный подход с помощью авторизации Google кажется мне излишним.

Мои данные должны быть доступны для чтения ВСЕМ, но доступны для записи только моим PHP-сервером.

До сих пор я мог гарантировать, что операция записи могла произойтитолько если в отправленном наборе данных указан определенный код (auth = 123):

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.resource.data.auth==123
      //request.auth.uid != null;
    }
  }
}

Проблема в том, что, поскольку каждый может читать данные, очень легко найти это поле (auth) и узнатьэто код 123.

Возможен любой из двух вариантов:

  1. Отправка заголовков (или других данных, не записанных в данные БД) и проверка этих правилвместо полей данных?

  2. В противном случае (менее предпочтительно) можно было бы скрыть ТОЛЬКО поле «auth» для пользователей?

Я знаю, что вариант 2 невозможен впринцип, но это можно как-то обойти, даже если я не знаю как.

Хотя я понимаю, что это не лучший подход, этого было бы более чем достаточно для защиты моего приложения.

EDIT

Вероятно, самым простым и чистым решением было бы создать пользователя в Firestore db с парой электронной почты / паролем и использовать его в запросе PHP curl

Я думаю, что янеобходимо выполнить запрос curl следующим образом:

https://firebase.google.com/docs/reference/rest/auth/#section-sign-in-email-password

и затем выполнить загрузку данных через другой PHP curl, используя в качестве аутентификации токен, полученный в первом запросе

Я чувствую, что это верный путь, но .... Я застреваю при первом запросе с

 404. That’s an error.

The requested URL /identitytoolkit/v3/relyingparty/verifyPassword?key=myapiket was not found on this server. That’s all we know.

Мне кажется, что я плохо сформулировал свой запрос локона ... любое предложение о том, как правильно обработатьполезная нагрузка?

РЕШЕНИЕ

Смотрите мой ответ ниже с шагами и кодом PHP

Ответы [ 2 ]

0 голосов
/ 22 февраля 2019

РЕШЕНИЕ

Хорошо, я нашел решение для достижения простой, но эффективной аутентификации при использовании Firebase Firestore REST API, используемого через curl PHP.

1 - СоздатьПроект Firebase

2- В моем случае мне нужно, чтобы каждый мог читать данные, и только один пользователь мог писать данные.Поэтому в «База данных / Правила» я поместил:

service cloud.firestore {
  match /databases/{database}/documents {
    match /{document=**} {
      allow read, write: if request.auth.uid != null;
    }
  }
}

3 - В «Способе аутентификации / входа» включите «Email / Password» в качестве поставщика входа

4- В разделе «Аутентификация / Пользователи» добавьте пользователя и укажите пару «адрес электронной почты / пароль»

5- Определите ключ API вашего проекта, который можно найти в разделе «Обзор проекта / Настройки / Общие / Ключ Web API»

6- Выполните запрос скручивания, чтобы получить идентификатор токена, который проверяется с помощью имени пользователя и пароля, и используйте этот токен для проверки действия Firestore.Код ниже:

<?php 

// 1) Retrieve Authorization TOKEN
// https://firebase.google.com/docs/reference/rest/auth/#section-sign-in-email-password
$firestore_key = "MY_KEY";

$url = "https://www.googleapis.com/identitytoolkit/v3/relyingparty/verifyPassword";

$postfields  = array(
        "email" => 'email@domain.com',
        "password" => 'password123456',
        "returnSecureToken" => true
    );

$datapost = json_encode($postfields);

$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => array('Content-Type: application/json'),
    CURLOPT_URL => $url . '?key='.$firestore_key,
    CURLOPT_USERAGENT => 'cURL',
    CURLOPT_POSTFIELDS => $datapost
));


$response = curl_exec( $curl );

curl_close( $curl );

$responsJson=json_decode($response,true);

// 2) Add data
//https://medium.com/@aliuwahab/firestore-firebase-php-saving-data-to-a-firestore-database-using-php-curl-2921da3b0ed4

$ID=10000001;

$firestore_data  = [
        "status" => ["integerValue" => 1500]
    ];

$data = ["fields" => (object)$firestore_data];

//    Possible *value options are:
//    stringValue
//    doubleValue
//    integerValue
//    booleanValue
//    arrayValue
//    bytesValue
//    geoPointValue
//    mapValue
//    nullValue
//    referenceValue
//    timestampValue

$json = json_encode($data);

#Provide your firestore project ID Here
$project_id = "myspecific_project"; //found in "Database/Data"

#Provide your firestore documents group
$documents_group = "my_group";

// https://stackoverflow.com/questions/50866734/rest-api-firestore-authentication-with-id-token/50866783#50866783
$url = "https://firestore.googleapis.com/v1beta1/projects/$project_id/databases/(default)/documents/$documents_group/$ID/";

$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST => 'POST',
    CURLOPT_HTTPHEADER => array('Content-Type: application/json',
        'Content-Length: ' . strlen($json),
        'X-HTTP-Method-Override: PATCH',
        'Authorization: Bearer '.$responsJson['idToken']        
        ),
    CURLOPT_URL => $url . '?key='.$firestore_key ,
    CURLOPT_USERAGENT => 'cURL',
    CURLOPT_POSTFIELDS => $json
));


$response = curl_exec( $curl );

curl_close( $curl );

// Show result
echo $response . "\n";

?>

ПРИМЕЧАНИЕ: В коде я отметил ссылки на информацию, которая помогла мне найти работающее решение

0 голосов
/ 21 февраля 2019

Невозможно отправить пользовательские заголовки с вашим запросом.Или точнее: эти заголовки не будут доступны в ваших правилах безопасности.См. В Firebase Firestore, есть ли способ передать информацию в Правила безопасности, которая не является частью пути? , Доступ к файлам cookie в правиле Google Firestore и Как разрешитьконкретный API для запуска запросов на запись / чтение в firestore? .

Также невозможно скрыть одно поле документа через правила безопасности.Либо документ полностью доступен для пользователя, либо он полностью недоступен.См. Firestore: ограничение доступа детей / полей с помощью правил безопасности и Защита определенных полей документа в Firestore .

Ваша единственная реальная возможность - аутентифицировать ваш PHP-скрипт и передатьтокен в вызове, а затем убедитесь, что ваш сервер вносит изменения.

...