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 令牌。
我正在使用 ESP32 将图像上传到 Firebase 存储,但通过底层 Google 云存储 JSON API。因此,我使用 Firebase Rest API 作为用户进行身份验证,然后检索 ID 令牌以用于存储上传。
但是,我在使用该 ID 令牌时收到 401 未授权错误。但是,直接将 ID 令牌替换为来自 Playground 的 OAuth2.0 令牌,范围为 https://www.googleapis.com/auth/devstorage.read_write
,效果很好;我可以看到图像在 Firebase 控制台中弹出。
我看到了
我的代码如下:
#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 令牌。