2016-07-07 77 views
1

我正嘗試創建一個簽名的URL,以便使用Go中編寫的App Engine應用程序從Google雲端存儲中下載文件。在我使用的App Engine中有一種漂亮的簽名方法,它[理論上]允許我避免將私鑰放入我的應用中。但是,這些網址似乎不起作用:我總是收到403「SignatureDoesNotMatch」錯誤。有任何想法嗎?在App Engine中創建簽名URL時遇到問題

下面的代碼:

func createDownloadURL(c context.Context, resource string, validUntil time.Time, bucket string) (string, error) { 
    serviceAccount, err := appengine.ServiceAccount(c) 
    if err != nil { 
    return "", err 
    } 

    // Build up the string to sign. 
    validUntilString := strconv.FormatInt(validUntil.Unix(), 10) 
    toSign := []string{ 
    "GET",   // http verb (required) 
    "",    // content MD5 hash (optional) 
    "",    // content type (optional) 
    validUntilString, // expiration (required) 
    resource,   // resource (required) 
    } 

    // Sign it. 
    _, signedBytes, err := appengine.SignBytes(c, []byte(strings.Join(toSign, "\n"))) 
    if err != nil { 
    return "", err 
    } 
    signedString := base64.StdEncoding.EncodeToString(signedBytes) 

    // Build and return the URL. 
    arguments := url.Values{ 
    "GoogleAccessId": {serviceAccount}, 
    "Expires":  {validUntilString}, 
    "Signature":  {signedString}, 
    } 
    return fmt.Sprintf("https://storage.googleapis.com/%s/%s?%s", bucket, resource, arguments.Encode()), nil 
} 

回答

1

已解決。我的代碼有兩個問題。

我在建立到簽名時忘記了包含存儲桶名稱。修復:

fmt.Sprintf("/%s/%s", bucket, resource),   // resource (required) 

這返回一個AccessDenied錯誤 - 進度!

第二個錯誤是使用XML API storage.googleapis.com而不是經過身份驗證的瀏覽器端點storage.cloud.google.com。修復:

return fmt.Sprintf("https://storage.cloud.google.com/%s/%s?%s", bucket, resource, arguments.Encode()), nil 

This Works。

0

StringToSign可能需要未解釋換行。你可以試試這個:

_, signedBytes, err := appengine.SignBytes(c, []byte(strings.Join(toSign, "\\n"))) // escaped newline 
+0

感謝您的建議。它似乎沒有幫助。 –

0

編寫一個標記URL的函數是非常棘手的,因爲由於加密的性質,當事情不起作用時很難分辨出什麼是錯誤的。您可能會發現使用像gcloud-golang這樣的庫更容易,該庫有一個SignedURL方法。

+0

謝謝 - 一個很好的建議。該庫要求我提供私鑰,而appengine.SignBytes爲我管理密鑰。如果我在任何地方做這些事情,除了appengine,我會使用這種方法。 –

+0

這是一個很好的觀點。我已經提交了一個功能請求:https://github.com/GoogleCloudPlatform/gcloud-golang/issues/286 –

+1

更新:這是一個功能:) –

相關問題