Squeak.ru - шаблоны программирования

Подписанные URL-адреса Google Cloud Storage с Google App Engine

Неприятно иметь дело с обычными подписанными URL-адресами (аутентификация строки запроса) для Google Cloud Storage.

Пример подписанных URL-адресов Google Cloud Storage -> Действительно ли это единственный код, доступный во всем Интернете для создания подписанных URL-адресов для Облачное хранилище Google? Должен ли я прочитать все это и при необходимости адаптировать вручную для Pure Python GAE?

Нелепо сравнивать его с AWS S3 getAuthenticatedURL(), уже включенным в любой SDK...

Я пропустил что-то очевидное или все сталкиваются с одной и той же проблемой? В чем дело?


  • Зачем вообще нужен подписанный URL? 21.02.2014
  • @AndreiVolgin Я не хочу, чтобы у моих пользователей были учетные записи Google. Мне просто нужны временные аутентифицированные URL-адреса. 21.02.2014
  • @AndreiVolgin Это интересное решение, но мне придется платить, например, за часы таким образом, вместо того, чтобы просто обслуживать файл непосредственно из GCS. Если бы мое приложение не было размещено в GAE, мне также пришлось бы платить за передачу данных по сети... 21.02.2014
  • Если у вас много пользователей, используйте инстанс Compute Engine — это в разы дешевле. Если у вас пока немного пользователей, возможно, вы находитесь в пределах бесплатной квоты в GAE. 21.02.2014

Ответы:


1

Вот как это сделать в 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
}
26.10.2014

2

Я понятия не имею, почему документы очень плохо. Единственный другой всесторонний ответ на SO великолепен, но утомителен.

Введите метод generate_signed_url. Заглянув в кроличью нору, вы заметите, что путь кода при использовании этого метода такой же, как и решение в приведенном выше сообщении 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
03.07.2017

3

Недавно я столкнулся с этой проблемой и нашел решение сделать это на питоне в GAE, используя встроенную учетную запись службы. Используйте функцию sign_blob() в google.appengine. api.app_identity, чтобы подписать строку подписи, и использовать get_service_account_name() в том же пакете, чтобы получить значение для GoogleAccessId.

Не знаю, почему это так плохо документировано, даже зная, что теперь это работает, я не могу найти никаких намеков с помощью поиска Google, что для этой цели можно использовать встроенную учетную запись. Хотя очень приятно, что это работает!

02.01.2015
  • Спасибо большое. Это прекрасно работает без pycrypto. Даже в SDK. 24.04.2015
  • И мой код здесь: stackoverflow.com/questions/29847759/ 24.04.2015

  • 4

    Посетите 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))
    
    28.02.2014
  • Есть ли что-то подобное для google app engine python? gcloud, кажется, имеет слишком много накладных расходов? 05.11.2014
  • Я только что немного подумал об этом - ошибка ImportError: No module named OpenSSL - однако вы используете только криптографию для преобразования p12 в pem-ключ, поэтому я просто собираюсь сгенерировать свой pem-ключ в автономном режиме и загрузить его к движку приложения. Поэтому я должен быть в состоянии удалить эти зависимости 06.11.2014

  • 5

    И если вы не хотите писать его самостоятельно, посмотрите этот класс на GitHub.

    Действительно прост в использовании

    GCSSignedUrlGenerator

    24.11.2014
    Новые материалы

    Угловая структура архитектуры
    Обратите внимание, что эта статья устарела, я решил создать новую с лучшей структурой и с учетом автономных компонентов: https://medium.com/@marekpanti/angular-standalone-architecture-b645edd0d54a..

    «Данные, которые большинство людей используют для обучения своих моделей искусственного интеллекта, поставляются со встроенным…
    Первоначально опубликовано HalkTalks: https://hacktown.com.br/blog/blog/os-dados-que-a-maioria-das-pessoas-usa-para-treinar-seus-modelos-de-inteligencia-artificial- ja-vem-com-um-vies-embutido/..

    Сильный ИИ против слабого ИИ: различия парадигм искусственного интеллекта
    В последние годы изучению и развитию искусственного интеллекта (ИИ) уделяется большое внимание и прогресс. Сильный ИИ и Слабый ИИ — две основные парадигмы в области искусственного интеллекта...

    Правильный способ добавить Firebase в ваш проект React с помощью React Hooks
    React + Firebase - это мощная комбинация для быстрого и безопасного создания приложений, от проверки концепции до массового производства. Раньше (знаете, несколько месяцев назад) добавление..

    Создайте API с помощью Python FastAPI
    Создание API с помощью Python становится очень простым при использовании пакета FastAPI. После установки и импорта вы можете создать приложение FastAPI и указать несколько конечных точек. Каждой..

    Веселье с прокси-сервером JavaScript
    Прокси-серверы JavaScript — это чистый сахар, если вы хотите создать некоторую общую логику в своих приложениях, чтобы облегчить себе жизнь. Вот один пример: Связь клиент-сервер Мы..

    Получить бесплатный хостинг для разработчиков | Разместите свой сайт за несколько шагов 🔥
    Статические веб-сайты — это веб-страницы с фиксированным содержанием и его постоянным содержанием. Но теперь статические сайты также обрабатывают динамические данные с помощью API и запросов...