Облачное хранилище и безопасная стратегия загрузки на движке приложений. GCS acl или blobstore

Мое приложение appengine создает файлы облачного хранилища. Файлы будут загружены третьей стороной. Файлы содержат личную медицинскую информацию.

Какой будет предпочтительный способ загрузки:

  1. Использование прямой ссылки на скачивание GCS с пользователем READER acl.
  2. Или с помощью обработчика загрузки из магазина приложений в приложении appengine.

Оба решения требуют, чтобы третье лицо входило в систему (google login). Производительность не проблема. Конфиденциальность и возникновение ошибок безопасности и ошибок.

Использование зашифрованного почтового файла для загрузки является вариантом. Это означает, что я должен хранить пароль в проекте. Или по электронной почте случайный пароль?

Обновление кода приложения, который я использовал для создания подписанного URL-адреса для загрузки

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 ответ

Решение

Если у небольшого числа пользователей есть доступ ко всем файлам в корзине, то решения № 1 будет достаточно, так как управление ACL не будет слишком большой болью.

Однако, если у вас много разных пользователей, которым требуется разный доступ к разным файлам в корзине, решение № 1 нецелесообразно.

Я бы также избежал решения № 2, поскольку вы будете платить за ненужную входящую / исходящую пропускную способность GAE.

Возможно, третье решение, которое стоит рассмотреть, - это использовать аутентификацию дескриптора App Engine и написать логику, чтобы определить, какие пользователи имеют доступ к каким файлам. Затем, когда файл запрашивается для загрузки, вы создаете подписанные URL-адреса для загрузки данных непосредственно из GCS. Вы можете установить для параметра expiration значение, которое вам подходит, что приведет к аннулированию URL-адреса через заданный промежуток времени.

Другие вопросы по тегам