简单(和)肮脏的Firestore身份验证规则 [英] SImple (and) dirty Firestore authentication rule

查看:124
本文介绍了简单(和)肮脏的Firestore身份验证规则的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在PHP项目中使用REST API,通过curl(PHP curl)将数据发送到Firestore DB。

I'm using REST API in a PHP project to send the data to Firestore DB through curl (PHP curl).

我在努力了解如何设置服务的身份验证规则,通过Google授权的建议方法对我来说似乎是过大的。

I'm struggling in understanding how to setup an authentication rule for a "service" and the suggested approach through Google authorization looks overkilling to me.

我的数据必须对所有人都可读,但只能由我的PHP服务器写入

My data must be readable by ALL but writable just by my PHP server.

到目前为止,我可以确保只有在数据集中发送了特定代码(auth = 123)的情况下,才可以进行写操作:

So far I could ensure that a writing operation could happen only if in the dataset sent a specific code is provided (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是代码。

Problem is that, as everybody can read the data, it's very easy to find this field (auth) and to know that 123 is the code.

这两种方式中的任何一种都可能:

Would be possible any of the two:


  1. 发送标头(或其他未记录到DB数据中)并执行规则检查而不是数据字段吗?

  1. Send headers (or other not recorded into DB data) and perform a rule check against that instead of the data fields?

否则(较不受欢迎)可以仅向用户隐藏 auth字段吗?

Otherwise (less preferred) would be possible to hide ONLY the field "auth" to the users?

我知道原则上不可能选择2,但是即使我不知道如何也可以解决此问题。

I know option 2 is not possible in principle but it might be worked around somehow even if I don't know how.

虽然我知道这不是最好的方法,但足以保护我的应用程序安全。

While I understand this is not the best approach, it would be more than enough to secure my application.

编辑

可能最简单的解决方案是在Firestore db中创建一个具有一对电子邮件/密码的用户,并在PHP curl请求中使用该用户

Probably the simplest cleanest solution would be to create an user in Firestore db with a pair email/password and use that in the PHP curl request

我认为我需要o在此之后发出卷曲请求:

I think I need to issue a curl request following this:

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

然后通过另一个PHP curl发出数据上传,使用在第一个请求中收到的令牌作为auth

And then issuing the upload of the data through another PHP curl using as auth the token received in the first request

就像这是正确的路径,但是...。我在第一个请求中遇到了问题

I feel like it's the right path but.... I get stuck at the first request with

 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.

我觉得我对卷曲的要求不好...关于如何正确处理有效载荷的任何建议?

I feel like I badly shaped my curl request... any suggestion on how to handle properly the payload?

解决方案

请参阅下面的步骤和PHP代码查看我的答案

See my answer below with steps and PHP code

推荐答案

解决方案

好,我发现当使用通过curl PHP使用的Firebase Firestore REST API时,可实现简单但有效的身份验证的解决方案。

Ok, I found the solution to achieve a simple but effective authentication when using Firebase Firestore REST API used through curl PHP.

1-创建Firebase项目

1- Create a Firebase project

2-在我的情况下,我需要每个人都能够读取数据并且只有一个用户可以写入数据。因此,在数据库/规则中,我输入:

2- In my case I need everybody to be able to read data and only one user to write data. So in "Database/Rules" I've put:

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

3-在身份验证/登录方法启用电子邮件/密码作为登录提供者

3- In "Authentication/Sign-In Method" enable "Email/Password" as Sign-In Provider

4-在身份验证/用户中,添加用户并提供一对电子邮件/密码

4- In "Authentication/Users", add a user and provide a pair "email/password"

5-标识您的项目API密钥,可在项目概述/设置/常规/ Web API密钥中找到

5- Identify your project API key which can be found in "Project Overview/Settings/General/Web API Key"

6-发出curl请求以获得通过用户名和密码进行验证的tokenId,并使用此令牌来验证Firestore操作。下面的代码:

6- Issue a curl request to obtain a tokenId which is validate through username and password and use this token to validate the Firestore action. Code below:

<?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";

?>

注意:在代码中,我标记了对帮助我的信息的链接提出可行的解决方案

NOTE: In the code I marked down links to information that helped me coming out with a working solution

这篇关于简单(和)肮脏的Firestore身份验证规则的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆