简单(和)脏Firestore身份验证规则

简单(和)脏Firestore身份验证规则,rest,curl,firebase-authentication,google-cloud-firestore,firebase-security,Rest,Curl,Firebase Authentication,Google Cloud Firestore,Firebase Security,我在一个PHP项目中使用RESTAPI,通过curl(PHP curl)将数据发送到Firestore DB 我正在努力理解如何为“服务”设置身份验证规则,而建议的通过谷歌授权的方法在我看来过于苛刻 我的数据必须可以被所有人读取,但只能被我的PHP服务器写入 到目前为止,我可以确保只有在发送的数据集中提供了特定代码(auth=123)时才能执行写入操作: 问题是,因为每个人都可以读取数据,所以很容易找到这个字段(auth)并知道123就是代码 可能是以下两种情况之一: 发送标题(或其他未记录到D

我在一个PHP项目中使用RESTAPI,通过curl(PHP curl)将数据发送到Firestore DB

我正在努力理解如何为“服务”设置身份验证规则,而建议的通过谷歌授权的方法在我看来过于苛刻

我的数据必须可以被所有人读取,但只能被我的PHP服务器写入

到目前为止,我可以确保只有在发送的数据集中提供了特定代码(auth=123)时才能执行写入操作:

问题是,因为每个人都可以读取数据,所以很容易找到这个字段(auth)并知道123就是代码

可能是以下两种情况之一:

  • 发送标题(或其他未记录到DB数据中的标题),并对其而不是数据字段执行规则检查

  • 否则(不太可取)可能只向用户隐藏字段“auth”

  • 我知道选择2原则上是不可能的,但它可能会以某种方式得到解决,即使我不知道如何解决

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

    编辑

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

    我想我需要发出以下curl请求:

    然后使用在第一个请求中接收到的令牌作为auth,通过另一个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代码。无法随请求发送自定义标题。或者更准确地说:这些标题在您的安全规则中不可用。看,还有

    也不可能通过安全规则隐藏文档的单个字段。文档对于用户来说是完全可访问的,或者是完全不可访问的。见和


    您唯一的实际选择是验证您的PHP脚本并将令牌传递到调用中,然后验证是您的服务器在进行更改。

    解决方案

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

    1-创建Firebase项目

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

    service cloud.firestore {
      match /databases/{database}/documents {
        match /{document=**} {
          allow read, write: if request.auth.uid != null;
        }
      }
    }
    
    3-在“身份验证/登录方法”中启用“电子邮件/密码”作为登录提供商

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

    5-确定您的项目API密钥,可在“项目概述/设置/常规/Web API密钥”中找到

    6-发出curl请求以获取通过用户名和密码验证的令牌ID,并使用此令牌验证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";
    
    ?>
    

    你的解决方案救了我一天,伙计!!谢谢。
    
    <?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";
    
    ?>