如何在应用程序引擎Python上创建Google云存储签名URL

如何在应用程序引擎Python上创建Google云存储签名URL,python,google-app-engine,google-cloud-storage,Python,Google App Engine,Google Cloud Storage,我找不到一个简单的例子来说明如何使用Python在Google App Engine上实现Google云存储签名URL。请写一份循序渐进的指南。:) 以下是我们是如何做到这一点的: 步骤1:获取p12文件/证书 从下载p12文件 “API和身份验证/凭据”选项卡 步骤2:将p12文件转换为DER格式 查找打开的Linux计算机并使用终端进行连接 命令: openssl pkcs12-in-nodes-nocerts> #p12文件的当前谷歌密码为notasecret 命令: openssl rs

我找不到一个简单的例子来说明如何使用Python在Google App Engine上实现Google云存储签名URL。请写一份循序渐进的指南。:)

以下是我们是如何做到这一点的:

步骤1:获取p12文件/证书

从下载p12文件 “API和身份验证/凭据”选项卡

步骤2:将p12文件转换为DER格式

查找打开的Linux计算机并使用终端进行连接 命令: openssl pkcs12-in-nodes-nocerts> #p12文件的当前谷歌密码为
notasecret

命令: openssl rsa-输入-通知PEM-输出-输出

步骤3:将DER文件转换为base64编码字符串

Python控制台:

private_key = open(‘<filename.der>’, 'rb').read()
print private_key.encode('base64')
步骤5:创建签名URL的Python代码

import Crypto.Hash.SHA256 as SHA256
import Crypto.PublicKey.RSA as RSA
import Crypto.Signature.PKCS1_v1_5 as PKCS1_v1_5

der_key = “””<copy-paste-the-base64-converted-key>”””.decode('base64')

bucket = <your cloud storage bucket name (default is same as app id)>
filename = <path + filename>

valid_seconds = 5
expiration = int(time.time() + valid_seconds)

signature_string = 'GET\n\n\n%s\n' % expiration
signature_string += bucket + filename



# Sign the string with the RSA key.
signature = ''
try:
  start_key_time = datetime.datetime.utcnow()
  rsa_key = RSA.importKey(der_key, passphrase='notasecret')
  #objects['rsa_key'] = rsa_key.exportKey('PEM').encode('base64')
  signer = PKCS1_v1_5.new(rsa_key)
  signature_hash = SHA256.new(signature_string)
  signature_bytes = signer.sign(signature_hash)
  signature = signature_bytes.encode('base64')

  objects['sig'] = signature
except:
  objects['PEM_error'] = traceback.format_exc()

try:
  # Storage
  STORAGE_CLIENT_EMAIL = <Client Email from Credentials console: Service Account Email Address>
  STORAGE_API_ENDPOINT = 'https://storage.googleapis.com'

  # Set the query parameters.
  query_params = {'GoogleAccessId': STORAGE_CLIENT_EMAIL,
                'Expires': str(expiration),
                'Signature': signature}


  # This is the signed URL:
  download_href = STORAGE_API_ENDPOINT + bucket + filename + '?' + urllib.urlencode(query_params)

except:
  pass
将Crypto.Hash.SHA256导入为SHA256
将Crypto.PublicKey.RSA导入为RSA
将Crypto.Signature.PKCS1_v1_5导入为PKCS1_v1_5
顺序键=“”。解码('base64')
桶=
文件名=
有效时间=5秒
expiration=int(time.time()+有效时间秒)
签名\u字符串='GET\n\n\n%s\n'%1!'
签名\u字符串+=存储桶+文件名
#使用RSA密钥对字符串进行签名。
签名=“”
尝试:
start\u key\u time=datetime.datetime.utcnow()
rsa_key=rsa.importKey(der_key,passphrase='notasecret')
#对象['rsa_key']=rsa_key.exportKey('PEM').encode('base64'))
签名者=PKCS1\u v1\u 5.新(rsa\u密钥)
签名\u散列=SHA256.new(签名\u字符串)
signature\u bytes=signer.sign(signature\u hash)
signature=signature\u bytes.encode('base64'))
对象['sig']=签名
除:
对象['PEM_error']=traceback.format_exc()
尝试:
#储藏
存储\客户端\电子邮件=
存储\u API\u端点编辑器https://storage.googleapis.com'
#设置查询参数。
query_params={'GoogleAccessId':存储\u客户端\u电子邮件,
“过期”:str(过期),
“签名”:签名}
#这是已签名的URL:
下载_href=STORAGE_API_ENDPOINT+bucket+filename+'?'+urllib.urlencode(查询参数)
除:
通过
来源

我创建了此回购协议:

使用GAE Pyrthon
app\u identity.get\u service\u account\u name()
app\u identity.sign\u blob()
使得创建签名url非常简单,无需使用PEM密钥。该应用程序显示如何下载GCS文件

但如果您使用SDK测试应用程序,则必须使用:

  • --appidentity\u电子邮件地址
  • --appidentity\u私钥\u路径

  • 因为创建签名url不是GCS客户端的一部分。

    其他解决方案也可以,但有一种更简单的使用方法。此方法与@voscausa的答案做的事情相同,但不太繁琐,并且具有自定义异常和对其他环境的支持

    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
    
    vascausa对本地开发服务器测试的看法

    但如果您使用SDK测试应用程序,则必须使用:

    --appidentity\u电子邮件地址

    --appidentity\u私钥\u路径

    因为创建签名url不是GCS客户端的一部分


    仍然有效。

    我尝试了这种方法,但出现了一个错误:
    AttributeError:您需要一个私钥来签署凭据。您当前使用的凭据只包含一个令牌。看见https://google-cloud-python.readthedocs.io/en/latest/core/auth.html?highlight=authentication#setting-up-a-service-account了解更多详细信息。
    我的印象是,这将在默认情况下起作用,因为服务使用默认服务帐户运行。我遗漏了什么?当将GOOGLE_APPLICATION_CREDENTIALS环境变量设置为与服务匹配的json密钥文件时,本地测试可以正常工作account@ajn我也遇到了同样的问题,你找到解决办法了吗?@AriVictor在我们的案例中,解决办法是我们用java实现它。不想麻烦地提供显式的服务帐户凭据,但也不想使用python 2.7。
    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