使用签名网址上传到Google云端存储时遇到问题

时间:2016-06-09 15:40:01

标签: google-app-engine google-cloud-storage

我在应用引擎端点中创建signedURL,然后将其提供给客户端。但是,当客户端尝试使用签名URL上载时,云存储会引发以下错误

Access denied. Anonymous users does not have storage.objects.create access to bucket

生成签名网址的应用引擎代码如下:

private String getSignedUrl() {
String encodedUrl = null;
String httpVerb = "PUT";
String contentMD5 = "";
String contentType = "image/rgb";

Calendar calendar = Calendar.getInstance();
calendar.add(Calendar.MINUTE, 10);
long expiration = calendar.getTimeInMillis() / 1000L;
String canonicalizedExtensionHeaders = "";
String canonicalizedResource =
    "/<bucket_name>/<folder_name>/";

String stringToSign =
    httpVerb + "\n" + contentMD5 + "\n" + contentType + "\n"
        + expiration + "\n" + canonicalizedExtensionHeaders
        + canonicalizedResource;

AppIdentityService service =
    AppIdentityServiceFactory.getAppIdentityService();
String googleAccessId = service.getServiceAccountName();

String baseURL =
    "http://storage.googleapis.com/<bucket_name>/<folder-name>/";
SigningResult signingResult =
    service.signForApp(stringToSign.getBytes());
String encodedSignature = null;
try {
    encodedSignature =
        URLEncoder.encode(
            new String(Base64.encodeBase64(
                signingResult.getSignature(), false),
                "UTF-8"), "UTF-8").toString();
} catch (UnsupportedEncodingException e) {
    // TODO Auto-generated catch block
    e.printStackTrace();
}
encodedUrl =
    baseURL + "?GoogleAccessId=" + googleAccessId + "&Expires="
        + expiration + "&Signature=" + encodedSignature;

return encodedUrl;
}

获取签名的URL后,我使用cURL来测试上传。我使用以下命令上传文件

curl -X PUT -H "Content-Type: multipart/form" -F file=@"<file_path>";type=image/rgb <signed_url>

我在cURL中尝试了POST和PUT,结果相同。 我在这里错过了什么吗?

2 个答案:

答案 0 :(得分:1)

从内存写入此处,但我认为您需要提供对象名称。另外,您在baseURL中包含了文件夹名称 - 只应包含存储桶名称。 “folder”名称是对象名称的一部分。

答案 1 :(得分:0)

由于服务帐户电子邮件中的googleAccessId符号,您还必须对encodedSignature@进行网址编码,而base64编码的字符串可能包含+字符由服务器解码为空间。