【问题标题】:Works via Postman but not in Flutter: API call with GCS pre-signed URL通过 Postman 工作,但不在 Flutter 中工作:使用 GCS 预签名 URL 的 API 调用
【发布时间】:2021-08-03 08:12:59
【问题描述】:

我正在尝试使用预签名的 URL 将视频文件上传到 GCS。我已经设法通过 Google 创建了 url,但现在我在使用它时遇到了问题。

在 Postman 中上传作品,得到响应 200。

postman body, postman params

从 Postman 复制的代码导致 403 Forbidden (SignatureDoesNotMatch):

Future<http.StreamedResponse> uploadVideo(
      {required String uploadURL, required String filePath}) async {
    var headers = {'Content-Type': 'application/octet-stream'};
    var request = http.MultipartRequest('PUT', Uri.parse(uploadURL));
    request.files.add(await http.MultipartFile.fromPath('file', filePath));
    request.headers.addAll(headers);

    http.StreamedResponse response = await request.send();

    if (response.statusCode == 200) {
      print(await response.stream.bytesToString());
    } else {
      print(response.reasonPhrase);
    }
    return response;
  }

这是我从 Google 得到的错误:

<?xml version='1.0' encoding='UTF-8'?><Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your Google secret key and signing method.</Message><StringToSign>GOOG4-RSA-SHA256
20210803T082850Z
20210803/auto/storage/goog4_request
6d513846a3db49f949b0d2eea8f04b90f918b3b94588c3ed55ed3620b7d7e1f6</StringToSign><CanonicalRequest>PUT
/phonedo-interviews/app-test/007/2.mp4
X-Goog-Algorithm=GOOG4-RSA-SHA256&amp;X-Goog-Credential=interviews%40interviews-317011.iam.gserviceaccount.com%2F20210803%2Fauto%2Fstorage%2Fgoog4_request&amp;X-Goog-Date=20210803T082850Z&amp;X-Goog-Expires=900&amp;X-Goog-SignedHeaders=content-type%3Bhost
content-type:multipart/form-data; boundary=dart-http-boundary-6w1yq6BQN3EkGBrhHZnwidOXZsBecsgSwTT3nBjB9vQCToHt0cg
host:storage.googleapis.com

content-type;host
UNSIGNED-PAYLOAD</CanonicalRequest></Error>

注意:我需要 Content-Type 成为 application/octet-stream,所以我在 Postman 的自动标题中禁用了该标题并手动添加了 Content-Type。当我没有这样做时,我也得到了 403。

【问题讨论】:

    标签: flutter dart postman pre-signed-url


    【解决方案1】:

    解决方案是以二进制形式发送文件。

    这是工作代码:

      Future<http.Response> uploadVideo(
          {required String uploadURL, required String filePath}) async {
        var response = await http.put(
          Uri.parse(uploadURL),
          headers: {'content-type': 'application/octet-stream'},
          body: File(filePath).readAsBytesSync(),
        );
    

    【讨论】:

      【解决方案2】:

      在您的 Postman 标头中,将 Token 提供给 GCS(第一行)。鉴于您需要授权,Postman 可能已将此 Token 保存在应用程序的某个地方。

      在这个颤振代码中,您提供的标头不包含 Auth 令牌,因此您会收到 403 错误。

      【讨论】:

      • 谢谢,但我使用的是不需要身份验证的预签名 URL。
      猜你喜欢
      • 2019-10-31
      • 1970-01-01
      • 2020-05-06
      • 2021-09-13
      • 1970-01-01
      • 2020-01-26
      • 2016-07-03
      • 2020-12-14
      • 2015-09-07
      相关资源
      最近更新 更多