Firebase ID 令牌是否未经授权上传到 Firebase/GCloud 存储?

Are Firebase ID Tokens unauthorized to upload to Firebase/ GCloud Storage?

我正在使用 ESP32 将图像上传到 Firebase 存储,但通过底层 Google 云存储 JSON API。因此,我使用 Firebase Rest API 作为用户进行身份验证,然后检索 ID 令牌以用于存储上传。

但是,我在使用该 ID 令牌时收到 401 未授权错误。但是,直接将 ID 令牌替换为来自 Playground 的 OAuth2.0 令牌,范围为 https://www.googleapis.com/auth/devstorage.read_write,效果很好;我可以看到图像在 Firebase 控制台中弹出。

我看到了 ,其中 Doug 提到了我正在尝试获得的功能,但显然存在错误。

我的代码如下:

#include "Arduino.h"
#include "globalVars.h"
#include "esp_camera.h"
#include <ArduinoJson.h>

#include <HTTPClient.h>

void checkMotion()
{
    delay(10000);
    camera_fb_t *fb = esp_camera_fb_get();
    uint8_t *fbBuf = fb->buf;
    size_t fbLen = fb->len;
    uint8_t *jpeg_buf = (uint8_t *)ps_malloc(fbLen);
    frame2jpg(fb, 2, &jpeg_buf, &fbLen);
    long currTime = millis();
    HTTPClient storageClient;
    String STORAGE_UPLOAD_PATH = NEW_OBJECT_BASE_PATH + String(currTime) + ".jpeg";
    storageClient.begin(STORAGE_UPLOAD_PATH);
    Serial.print("uploading to : ");
    Serial.println(STORAGE_UPLOAD_PATH);

    // Using the ID Token from Auth--doesn't work
    Serial.println(idToken); // successfully prints it out
    String bearerString = String("Bearer ") + String(idToken);
    storageClient.addHeader("Authorization", bearerString);

    // Using Playground token instead, and commenting the above--works!
    // storageClient.addHeader("Authorization", "Bearer MY_PLAYGROUND_TOKEN_IS_HERE");

    // Content type
    storageClient.addHeader("Content-Type", "image/jpeg");
    storageClient.addHeader("Content-Length", String(fbLen));
    int uploadResponseCode = storageClient.POST(jpeg_buf, fbLen);
    Serial.print("Response code: ");
    Serial.println(String(uploadResponseCode));
    
    String uploadResponseRaw = storageClient.getString();
    Serial.println("Received response:" + uploadResponseRaw);
    const size_t responseCapacity = JSON_OBJECT_SIZE(100);
    StaticJsonDocument<responseCapacity> dUploadResponse;
    DeserializationError deserializeResult = deserializeJson(dUploadResponse, uploadResponseRaw);
    Serial.println(deserializeResult.c_str());
    storageClient.end();
    free(jpeg_buf);
}

使用 idToken 时,这是我收到的响应:

{
  "error": {
    "code": 401,
    "message": "Invalid Credentials",
    "errors": [
      {
        "message": "Invalid Credentials",
        "domain": "global",
        "reason": "authError",
        "locationType": "header",
        "location": "Authorization"
      }
    ]
  }
}

在测试期间,我什至还设置了我的 Firebase 存储规则以简单地允许所有内容:

rules_version = '2';
service firebase.storage {
  match /b/{bucket}/o {
    match /{allPaths=**} {
      allow read, write: if true;
    }
  }
}

我错过了什么?提前致谢。

Firebase ID 令牌只能通过 Firebase SDK 使用。然后,Firebase 后端根据安全规则对 ID 令牌执行访问控制检查。

通过 GCP API 访问云存储会绕过 Firebase 服务器和安全规则,因此无法使用 Firebase ID 令牌来完成。您将不得不使用 OAuth 2 令牌。