Pre‑signed URL (или подписанный URL) — это ссылка, которая предоставляет временный доступ к частному объекту в облачном хранилище, минуя стандартные механизмы аутентификации. Она содержит криптографическую подпись, позволяющую серверу проверить, что у пользователя есть права на выполнение указанного в URL действия
🔑 Основные типы pre‑signed URL
Большинство облачных провайдеров (AWS S3, Google Cloud Storage, Yandex Cloud Object Storage и совместимые с ними S3-сервисы) поддерживают следующие HTTP-методы для pre‑signed URL:
1. GET – скачивание объекта
Самый распространённый тип. Позволяет клиенту скачать объект из защищённого бакета без использования постоянных ключей доступа. Например, вы можете сгенерировать ссылку на отчёт, которая будет действительна только 5 минут.
# Пример на Python (boto3 для AWS S3)
url = s3_client.generate_presigned_url(
ClientMethod='get_object',
Params={'Bucket': 'my-bucket', 'Key': 'secret-report.pdf'},
ExpiresIn=300 # 5 минут
)
2. PUT – прямая загрузка объекта
Позволяет клиенту напрямую загрузить файл в бакет. Клиент отправляет HTTP‑запрос типа PUT с телом файла. URL блокируется под конкретный key, а также можно ограничить Content-Type или размер файла, чтобы защититься от нежелательной перезаписи.
# Пример генерации pre‑signed URL для PUT
url = s3_client.generate_presigned_url(
ClientMethod='put_object',
Params={'Bucket': 'my-bucket', 'Key': 'user-upload.jpg', 'ContentType': 'image/jpeg'},
ExpiresIn=3600 # 1 час
)
3. DELETE – удаление объекта
Редко используемый, но полезный тип. Клиент может удалить объект по временной ссылке. Обычно применяется в сценариях, где пользователю разрешено удалить свой собственный файл.
# Генерация pre‑signed URL для DELETE
url = s3_client.generate_presigned_url(
ClientMethod='delete_object',
Params={'Bucket': 'my-bucket', 'Key': 'temp-file.tmp'},
ExpiresIn=600 # 10 минут
)
4. POST – загрузка через HTML-форму
Отличается от PUT тем, что создаётся для метода POST и используется в HTML-формах (multipart/form-data). Позволяет передавать не только файл, но и дополнительные поля. В AWS S3 для этого есть специальный метод generate_presigned_post().
# Генерация pre‑signed POST данных
post_data = s3_client.generate_presigned_post(
Bucket='my-bucket',
Key='uploads/${filename}',
Fields={'success_action_redirect': 'https://myapp.com/success'},
Conditions=[
['content-length-range', 1, 10_000_000] # ограничение размера файла
],
ExpiresIn=3600
)
5. HEAD – получение метаданных
Позволяет клиенту проверить наличие объекта, его размер, тип содержимого и другие метаданные без скачивания всего файла. Полезно для проверок перед загрузкой/скачиванием.
📊 Сравнение PUT и POST для загрузки
🌐 Поддержка в различных облачных провайдерах
Примечание про HEAD: Хотя HEAD официально поддерживается, на практике многие разработчики вместо него используют GET с заголовком Range: 0, чтобы получить только первый байт и метаданные
🧪 Практические примеры генерации
AWS S3 (Python – boto3)
python
import boto3
from botocore.exceptions import NoCredentialsError
s3_client = boto3.client('s3')
# GET
get_url = s3_client.generate_presigned_url('get_object', Params={'Bucket': 'my-bucket', 'Key': 'my-file.pdf'}, ExpiresIn=300)
# PUT
put_url = s3_client.generate_presigned_url('put_object', Params={'Bucket': 'my-bucket', 'Key': 'upload.jpg'}, ExpiresIn=3600)
# DELETE
del_url = s3_client.generate_presigned_url('delete_object', Params={'Bucket': 'my-bucket', 'Key': 'temp.jpg'}, ExpiresIn=600)
# POST (специальный метод)
post_data = s3_client.generate_presigned_post(Bucket='my-bucket', Key='uploads/${filename}', ExpiresIn=3600)
# HEAD
head_url = s3_client.generate_presigned_url('head_object', Params={'Bucket': 'my-bucket', 'Key': 'my-file.pdf'}, ExpiresIn=300)
Yandex Cloud Object Storage (совместим с AWS S3)
Для Yandex Cloud используется тот же код, что и для AWS S3, но с указанием эндпоинта:
python
s3_client = boto3.client(
's3',
endpoint_url='https://storage.yandexcloud.net',
aws_access_key_id='<YOUR_ACCESS_KEY>',
aws_secret_access_key='<YOUR_SECRET_KEY>'
)
Google Cloud Storage (Python – google-cloud-storage)
python
from google.cloud import storage
client = storage.Client()
bucket = client.bucket('my-bucket')
blob = bucket.blob('my-file.pdf')
# GET
url = blob.generate_signed_url(version='v4', expiration=300, method='GET')
# PUT
url = blob.generate_signed_url(version='v4', expiration=3600, method='PUT')
⚠️ Важные нюансы
- Срок действия – Pre‑signed URL имеют ограниченное время жизни (от нескольких минут до 7 дней в зависимости от провайдера).
- Безопасность – Сам URL содержит подпись, поэтому его нельзя подделать. Но он даёт доступ к объекту, поэтому обращаться с ним нужно как с паролем (не хранить в логах, не передавать через небезопасные каналы).
- Передача URL – Вы должны отдать сгенерированный URL клиенту (обычно через ваш API). Клиент использует его напрямую для взаимодействия с хранилищем.
- Политики для POST – Метод POST позволяет задавать дополнительные ограничения (максимальный размер файла, точное имя ключа и т.д.) через POST Policy.
Если у вас есть конкретный кейс или нужны примеры для другого языка программирования — напишите, я дополню ответ.
Страховка на собеседовании
Знание есть, но стресс мешает?
Бесплатное сообщество для прокачки карьеры в IT
Подпишись на https://t.me/IT_Interview_Partner_Bot
Подпишись на https://t.me/LyakhovEugene