将签名URL用于可恢复上传到Google云端存储的正确方法是什么?

时间:2016-05-19 03:46:13

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

我正在尝试在我的App Engine代码中创建一个已签名的URL并将其传递给客户端以进行初始POST调用以获取可恢复的上载位置,遵循文档中的以下建议:

  

在未启动的区域内执行可恢复上传   导致上传速度慢。为避免这种情况,您可以进行初始POST   请求由服务器构造和签名,但随后给出签名   客户端的URL,以便从其位置启动上载。

但是,当客户端对签名URL进行POST调用时,此调用会导致错误401,这会告诉我Cloud Storage需要授权标头。

这是我签名的网址的样子:

https://www.googleapis.com/upload/storage/v1/b/myBucket/o?uploadType=resumable&name=fileName&GoogleAccessId=xxx@appspot.gserviceaccount.com&Expires=1463628862&Signature=IZNU%2B2ApaUlogY9CR%2B4DC09WKkIpeZLeuqzrudyxA0nETH7Wpr4x8aRZTZj%2BGOriCDL8JfnoyAFhY1XqMG7VU3VPliu7LXoDSvuH0Cjaoz5lefNs80HpneAHI7HpAX2Uv2Lr57ZwbXM3EoegGiTcJb3ck51VH0%2FxTWSnqxlJsgQzo9%2BYKVhkHBzFn29k7k76qsGhN91g5CfTtSKtfa%2FiYwCffoB%2BctIdULwKF7yMugNkLKAfqxrWRXVAmrzXUK9njGTOQqfcvAtq4jJ23Aflo6ETmDKghZuZNLqoHs5umEhFRC1eFGd%2Be10RDRON%2F1ysXahWawSx4YOE9bEZXPKNtQ%3D%3D

我在App Engine端使用相同的代码来生成下载的签名URL,它们工作正常。

这是组合初始POST调用的URL的正确方法吗?是否有其他原因导致此错误?

修改

生成网址的代码:

long expiration = System.currentTimeMillis()/1000 + 60;
String unsigned = stringToSign(expiration, gsKey, "POST");
String signature = sign(unsigned);
return new StringBuilder("https://www.googleapis.com/upload/storage/v1/b/")
        .append(BUCKET)
        .append("/o?uploadType=resumable&name=")
        .append(gsKey)
        .append("&GoogleAccessId=")
        .append(identityService.getServiceAccountName())
        .append("&Expires=")
        .append(expiration)
        .append("&Signature=")
        .append(URLEncoder.encode(signature, "UTF-8"))
        .toString();

private static String stringToSign(final long expiration, String gsKey, String httpVerb) {
    String contentType = "";
    String contentMD5 = "";
    String canonicalizedExtensionHeaders = "";
    String canonicalizedResource = "/" + BUCKET + "/" + gsKey;
    String stringToSign = httpVerb + "\n" +
            contentMD5 + "\n" +
            contentType + "\n" + 
            expiration + "\n" + 
            canonicalizedExtensionHeaders + "\n" +
            canonicalizedResource;
    return stringToSign;
}

private static String sign(final String stringToSign) throws UnsupportedEncodingException {
    SigningResult signingResult = identityService.signForApp(stringToSign.getBytes());
    String encodedSignature = new String(Base64.encodeBase64(signingResult.getSignature(), false), "UTF-8");
    return encodedSignature;
}

0 个答案:

没有答案