繁体   English   中英

使用Google App Engine的Google云端存储签名网址

[英]Google Cloud Storage Signed URLs with Google App Engine

处理Google云端存储的常规签名URL(查询字符串身份验证)令人沮丧。

Google云端存储签名网址示例 - >这是否是整个互联网中唯一可用于生成Google云端存储签名网址的代码? 如果需要,我应该全部阅读并手动修改Pure Python GAE吗?

当你将它与已经包含在任何SDK中的AWS S3 getAuthenticatedURL()进行比较时,这很荒谬......

我错过了一些明显的东西,还是每个人都面临同样的问题? 这是怎么回事?

以下是Go中的操作方法:

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
}

我最近也遇到了这个问题,并找到了一个解决方案,使用内置的服务帐户在GAE中的python中执行此操作。 使用google.appengine.api.app_identity包中的sign_blob()函数对签名字符串进行签名,并在同一个包中使用get_service_account_name()来获取GoogleAccessId的值。

不知道为什么这个文档记录太差,甚至现在知道这有效我无法使用谷歌搜索找到任何提示,为此目的应该可以使用内置帐户。 非常好,虽然它有效!

我不知道为什么文档如此糟糕。 关于SO的唯一其他综合答案是伟大但乏味的。

输入generate_signed_url方法 爬下兔子洞,你会注意到使用这种方法的代码路径与在GAE上执行的上述SO帖子中的解决方案相同。 然而,这种方法不那么繁琐,支持其他环境,并且具有更好的错误消息。

在代码中:

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

查看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': 'your-service-account@googleapis.com',
                '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))

如果您不想在GitHub上通过自己的结账这个类来编写它。

真的很容易使用

GCSSignedUrlGenerator

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM