10

處理Google雲端存儲的常規Signed URLs (Query String Authentication)令人沮喪。使用Google App Engine的Google雲端存儲簽名URL

Google Cloud Storage Signed URLs Example - >這是否真的是整個互聯網上唯一可用於生成Google Cloud Storage簽名URL的代碼?我是否應該閱讀所有內容,並根據需要手動修改純Python GAE?

當你與AWS S3 getAuthenticatedURL(),已經包含在任何SDK進行比較這是荒謬的......

我失去了一些東西明顯或每個人都面臨着同樣的問題?這是怎麼回事?

+0

爲什麼你需要擺在首位簽署的網址是什麼? –

+1

@AndreiVolgin我不想要求我的用戶擁有Google帳戶。我只需要臨時認證的URL。 –

+0

您可以從您的應用程序加載文件並將其提供給用戶。你不需要一個簽名的URL。 –

回答

1

退房https://github.com/GoogleCloudPlatform/gcloud-python/pull/56

在Python中,這樣做...

import base64 
import time 
import urllib 
from datetime import datetime, timedelta 

from Crypto.Hash import SHA256 
from Crypto.PublicKey import RSA 
from Crypto.Signature import PKCS1_v1_5 
from OpenSSL import crypto 

method = 'GET' 
resource = '/bucket-name/key-name' 
content_md5, content_type = None, None 

expiration = datetime.utcnow() + timedelta(hours=2) 
expiration = int(time.mktime(expiration.timetuple())) 

# Generate the string to sign. 
signature_string = '\n'.join([ 
    method, 
    content_md5 or '', 
    content_type or '', 
    str(expiration), 
    resource]) 

# Take our PKCS12 (.p12) key and make it into a RSA key we can use... 
private_key = open('/path/to/your-key.p12', 'rb').read() 
pkcs12 = crypto.load_pkcs12(private_key, 'notasecret') 
pem = crypto.dump_privatekey(crypto.FILETYPE_PEM, pkcs12.get_privatekey()) 
pem_key = RSA.importKey(pem) 

# Sign the string with the RSA key. 
signer = PKCS1_v1_5.new(pem_key) 
signature_hash = SHA256.new(signature_string) 
signature_bytes = signer.sign(signature_hash) 
signature = base64.b64encode(signature_bytes) 

# Set the right query parameters. 
query_params = {'GoogleAccessId': '[email protected]', 
       'Expires': str(expiration), 
       'Signature': signature} 

# Return the built URL. 
return '{endpoint}{resource}?{querystring}'.format(
    endpoint=self.API_ACCESS_ENDPOINT, resource=resource, 
    querystring=urllib.urlencode(query_params)) 
+0

谷歌應用程序引擎python是否有這樣的東西? gcloud似乎有太多開銷? –

+0

我只是有點想到這個 - 錯誤是「ImportError:No module named OpenSSL」 - 但是你只使用加密轉換p12到pem鍵,所以我只是離線生成我的pem密鑰並將其上傳到應用引擎。所以我應該能夠消除這些依賴關係 –

5

這裏是如何做到這一點圍棋:

func GenerateSignedURLs(c appengine.Context, host, resource string, expiry time.Time, httpVerb, contentMD5, contentType string) (string, error) { 
    sa, err := appengine.ServiceAccount(c) 
    if err != nil { 
     return "", err 
    } 
    expUnix := expiry.Unix() 
    expStr := strconv.FormatInt(expUnix, 10) 
    sl := []string{ 
     httpVerb, 
     contentMD5, 
     contentType, 
     expStr, 
     resource, 
    } 
    unsigned := strings.Join(sl, "\n") 
    _, b, err := appengine.SignBytes(c, []byte(unsigned)) 
    if err != nil { 
     return "", err 
    } 
    sig := base64.StdEncoding.EncodeToString(b) 
    p := url.Values{ 
     "GoogleAccessId": {sa}, 
     "Expires": {expStr}, 
     "Signature": {sig}, 
    } 
    return fmt.Sprintf("%s%s?%s", host, resource, p.Encode()), err 
} 
3

我碰到這個問題就最近也發現瞭解決內GAE爲此在使用Python中內置的服務帳戶。使用在google.appengine.api.app_identitysign_blob()函數簽署簽名字符串,並使用get_service_account_name()在同一封裝內獲得了GoogleAccessId值。

不知道爲什麼這是如此糟糕的記錄,即使現在知道這個工程我不能找到任何提示使用谷歌搜索,應該可以使用內置帳戶用於此目的。非常好,但它的工作原理!

+1

非常感謝。這很好,沒有pycrypto。即使在SDK上。 – voscausa

+1

而我的代碼在這裏:http://stackoverflow.com/questions/29847759/cloud-storage-and-secure-download-strategy-on-app-engine-gcs-acl-or-blobstore – voscausa

0

我不知道爲什麼the docs是如此糟糕。 SO上唯一的另一個comprehensive answer是偉大而乏味的。

輸入generate_signed_url method。爬下兔子洞,你會發現使用這種方法時的代碼路徑與上述SO帖子中的解決方案在GAE上執行時相同。然而,這種方法不那麼單調乏味,支持其他環境,並且具有更好的錯誤消息。

在代碼:

def sign_url(obj, expires_after_seconds=60): 

    client = storage.Client() 
    default_bucket = '%s.appspot.com' % app_identity.get_application_id() 
    bucket = client.get_bucket(default_bucket) 
    blob = storage.Blob(obj, bucket) 

    expiration_time = int(time.time() + expires_after_seconds) 

    url = blob.generate_signed_url(expiration_time) 

    return url 
相關問題