应用引擎上的云存储和安全下载策略。 GCS acl或blobstore

时间:2015-04-24 12:38:28

标签: google-app-engine authentication google-cloud-storage acl blobstorage

我的appengine应用创建了cloudstorage文件。这些文件将由第三方下载。这些文件包含个人医疗信息

下载的首选方式是什么:

  1. 使用直接GCS下载链接和用户READER acl。
  2. 或者在appengine app中使用blobstore下载处理程序。
  3. 两种解决方案都要求第三方登录(谷歌登录)。性能不是问题。隐私和安全错误和错误的发生是。

    使用加密的zip文件下载是一个选项。这意味着我必须将密码存储在项目中。或者通过电子邮件发送随机密码?

    更新我用于创建签名下载网址的附加代码

    import time
    import urllib
    from datetime import datetime, timedelta
    from google.appengine.api import app_identity
    import os
    import base64
    
    API_ACCESS_ENDPOINT = 'https://storage.googleapis.com'
    
    # Use the default bucket in the cloud and not the local SDK one from app_identity
    default_bucket = '%s.appspot.com' % os.environ['APPLICATION_ID'].split('~', 1)[1]
    google_access_id = app_identity.get_service_account_name()
    
    
    def sign_url(bucket_object, expires_after_seconds=60):
        """ cloudstorage signed url to download cloudstorage object without login
            Docs : https://cloud.google.com/storage/docs/access-control?hl=bg#Signed-URLs
            API : https://cloud.google.com/storage/docs/reference-methods?hl=bg#getobject
        """
    
        method = 'GET'
        gcs_filename = '/%s/%s' % (default_bucket, bucket_object)
        content_md5, content_type = None, None
    
        expiration = datetime.utcnow() + timedelta(seconds=expires_after_seconds)
        expiration = int(time.mktime(expiration.timetuple()))
    
        # Generate the string to sign.
        signature_string = '\n'.join([
            method,
            content_md5 or '',
            content_type or '',
            str(expiration),
            gcs_filename])
    
        _, signature_bytes = app_identity.sign_blob(signature_string)
        signature = base64.b64encode(signature_bytes)
    
        # Set the right query parameters.
        query_params = {'GoogleAccessId': google_access_id,
                        'Expires': str(expiration),
                        'Signature': signature}
    
        # Return the download URL.
        return '{endpoint}{resource}?{querystring}'.format(endpoint=API_ACCESS_ENDPOINT,
                                                           resource=gcs_filename,
                                                           querystring=urllib.urlencode(query_params))
    

1 个答案:

答案 0 :(得分:3)

如果少数用户可以访问存储桶中的所有文件,那么解决方案#1就足够了,因为管理ACL不会太痛苦。

但是,如果您有许多不同的用户,每个用户都需要对存储桶中的不同文件进行不同的访问,那么解决方案#1是不切实际的。

我也避免使用解决方案#2,因为您需要支付不必要的传入/传出GAE带宽。

可能需要考虑的第三个解决方案是使用App Engine句柄身份验证,并编写逻辑来确定哪些用户可以访问哪些文件。然后,当请求下载文件时,您创建Signed URLs以直接从GCS下载数据。您可以将expiration参数设置为适合您的值,这将在一段时间后使URL无效。