Ссылка на файл перестала работать: как проверить срок подписанного URL
Если подписанная ссылка S3 перестала открывать файл, сначала проверьте срок её действия, исходные учётные данные AWS и ответ хранилища. Ошибка доступа не доказывает удаление объекта. Новая ссылка помогает только тогда, когда сервер вправе выдать доступ к существующему файлу и правильно подписывает запрос. Разберём, как установить причину без публикации секретного URL, открытия приватного бакета и бессистемного увеличения срока.
1. Зафиксируйте, какая именно ссылка перестала работать
Начните с одной воспроизводимой попытки. Запишите внутренний ID документа, время выдачи ссылки, время открытия с часовым поясом, действие пользователя и сообщение об ошибке. Уточните, ссылка не сработала сразу, перестала работать спустя время или отказала при возобновлении скачивания. Это разные наблюдения, которые направляют проверку.
Отделите адрес страницы сайта от адреса хранилища. Пользователь может открыть сохранённую страницу заказа, получить от неё устаревший URL и увидеть отказ уже на S3. В другой ситуации сам сайт не выдаёт ссылку, потому что закончилась пользовательская сессия. Исправлять подпись во втором случае преждевременно: запрос к хранилищу ещё не состоялся.
Полный подписанный URL не нужен в общей задаче поддержки. Сохраните его только в предусмотренном закрытом контексте, если он необходим разработчику для анализа. Для основной карточки достаточно обезличенных временных параметров, метода, кода ошибки и идентификатора запроса S3. Не вставляйте рабочую ссылку в публичный проверяющий сервис, чат или пример статьи.
Сравнивайте результаты для одного документа и одной версии. Свежая ссылка на другой файл ничего не доказывает о старой. Если объект выбирается через внутреннюю запись приложения, зафиксируйте, какой ключ S3 был связан с ней в момент выдачи.
Полезно отметить, у кого проявляется отказ: у всех получателей, только у открывших старое письмо или только после длительной паузы. Не просите пользователей массово пересылать ссылки друг другу. Поддержка собирает время и внутренние номера, а разработчик проверяет связь с записью выдачи. Так можно сравнить случаи, сохранив контроль над доступом к документам.
2. Рассчитайте срок по параметрам SigV4
Для обычного S3 URL с подписью Signature Version 4 важны X-Amz-Date и X-Amz-Expires. По документации параметров подписи первый содержит время в UTC, второй — длительность в секундах. Не принимайте X-Amz-Expires за готовую дату и не путайте его с миллисекундами.
Ниже учебная диагностическая запись. Это отдельные извлечённые поля, а не рабочий URL; подпись, ключ и токен намеренно отсутствуют.
X-Amz-Date = 20261101T090000Z
X-Amz-Expires = 3600
X-Amz-SignedHeaders = host
Время подписи — 1 ноября 2026 года, 09:00 UTC. 3600 секунд равны 60 минутам, поэтому номинальная граница срока — 10:00 UTC. Если открытие произошло в 10:07 UTC, заявленный интервал уже закончился. Если в 09:20, одной этой арифметики недостаточно: существуют другие ограничения доступа.
Консоль S3 позволяет задавать срок до 12 часов, а AWS CLI — до семи дней; SDK также поддерживают срок до семи дней для соответствующего сценария SigV4. Это максимумы настройки, а не обещание, что любая ссылка проработает столько времени. Не устраняйте расхождение произвольным увеличением X-Amz-Expires внутри уже готового адреса: изменение подписанных параметров требует новой подписи.
3. Проверьте срок исходных credentials
Подписанный адрес использует полномочия того AWS principal, чьи credentials применялись при его создании. Если это временные данные сессии роли или AWS STS, ссылка не переживёт их истечение. Например, URL может иметь номинальный срок до 10:00, а исходная сессия — только до 09:40. После окончания сессии более длинное значение Expires не спасает запрос.
AWS отдельно описывает срок временных credentials: после его окончания запросы с ними не проходят; старый набор нельзя продлить за исходную границу. Приложению требуется получить действующие данные предусмотренным способом. Проверьте, использует ли генератор актуальный credential provider или однажды сохранил временный набор и продолжает подписывать им адреса.
Не ищите точный срок сессии только по внешнему виду URL. Разработчик должен установить происхождение credentials и их expiration на стороне генератора. В отчёте достаточно типа источника, времени окончания и результата обновления. Access key ID, session token и подпись не должны превращаться в общедоступные диагностические данные.
Обновление credentials и перевыпуск ссылки — разные шаги. Старый URL не получает новый срок автоматически после обновления серверного SDK. И сама ротация набора не равнозначна немедленному отзыву предыдущего: для конкретной попытки проверяют срок и действительность именно тех данных, которыми она подписана.
4. Найдите ограничения политики, сокращающие окно доступа
Срок подписи — лишь часть условий. У подписывающей роли должны оставаться необходимые права, а применимые политики не должны запрещать запрос. Проверяйте конкретный объект, операцию и условия доступа. Изменение политики способно объяснить, почему прежний URL отказал ещё до рассчитанного срока.
В рекомендациях AWS по дополнительным ограничениям описан s3:signatureAge. Он может ограничить возраст подписи сильнее, чем X-Amz-Expires. Значение измеряется в миллисекундах. Условие политики не продлевает ссылку, срок которой уже закончился.
| Учебное условие | Рассчитанная граница |
|---|---|
| Подпись в 09:00, Expires = 3600 секунд | 10:00 UTC |
| Исходная сессия действует до 09:40 | 09:40 UTC |
| Политика запрещает возраст подписи больше 900000 мс | Возраст 15 минут достигается в 09:15 UTC |
При точных часах и неизменных остальных условиях доступ в этом примере ограничен самым ранним из трёх рубежей. В 09:16 ссылка уже нарушает условие возраста, хотя Expires ещё указывает на часовой интервал. Значение 900000 ÷ 1000 ÷ 60 равно 15. Это учебная политика, не универсальное правило S3.
Проверьте и ограничения сетевого пути: разрешённая сеть, адрес источника или endpoint могут отличаться у сервера и покупателя. Успех из административной среды не гарантирует успех с устройства пользователя. Исправляйте конкретное несоответствие требованиям доступа, сохраняя приватность бакета и предусмотренные защитные настройки.
5. Прочитайте код ошибки, а не только HTTP-статус
Запрос «S3 ссылка Access Denied» описывает симптом слишком широко. Сохраните HTTP-статус и, если тело ответа доступно, поля Code, Message и RequestId. Справочник ошибок S3 различает причины, которые требуют разных действий.
| Наблюдение | Что проверить следующим |
|---|---|
| ExpiredToken | Действительность временных credentials, которыми создана ссылка |
| SignatureDoesNotMatch | Совпадение фактического запроса с подписанным |
| AccessDenied | Детали сообщения, срок, права и применимые политики |
| NoSuchKey | Правильность ключа и наличие нужного объекта |
| Нет HTTP-ответа | На каком этапе закончилась попытка соединения |
Не сводите все отказы к 403: например, ExpiredToken указан в документации с HTTP 400. И наоборот, один 403 не устанавливает точную причину. При наличии прокси убедитесь, что анализируете ответ S3, а не страницу запрета промежуточной системы.
Сообщение вроде presigned URL expired нужно сопоставить с временем и источником ответа. Если такую надпись формирует само приложение, выясните, на каком основании оно сделало вывод. Ошибка сетевого клиента без ответа хранилища не доказывает истечение подписи. Пока свидетельств недостаточно, сохраняйте причину как неизвестную, а не подменяйте её удобным объяснением.
6. Отдельно подтвердите существование файла
Для обычного GetObject отсутствующий объект может возвращать разные статусы. AWS указывает: при наличии s3:ListBucket возвращается 404, а без этого разрешения — 403. Поэтому по отказу подписанной ссылки нельзя уверенно заявить, что файл существует или был удалён.
Проверку выполняет уполномоченный сотрудник через штатный доступ к хранилищу. Сопоставьте бакет, полный ключ и при необходимости versionId с записью приложения. Проверьте, не изменилось ли имя при публикации, не выдана ли ссылка на старую версию экспорта и не сработал ли предусмотренный процесс удаления.
Не добавляйте пользователю широкие права на просмотр бакета только ради более удобного кода ошибки. У администратора и подписывающей роли могут быть разные полномочия, поэтому подтверждение наличия объекта и проверка доступа по URL остаются отдельными действиями.
Если объекта действительно нет, перевыпуск подписи на тот же отсутствующий ключ его не восстановит. Исправлять нужно публикацию, привязку документа или согласованный процесс восстановления. В обращении зафиксируйте этот результат отдельно от срока ссылки: это предотвратит бесконечную отправку новых адресов к несуществующему файлу.
7. Сверьте метод, адрес и подписанные заголовки
Подпись относится к определённому запросу. Проверяйте HTTP-метод, endpoint, ключ объекта, параметры и заголовки, участвовавшие в подписании. GET и HEAD не взаимозаменяемы: диагностический клиент, который проверяет GET-ссылку методом HEAD, может получить отказ из-за собственного способа проверки.
Руководство AWS по ошибкам SigV4 рекомендует сопоставлять сформированный и фактически отправленный запрос, включая область подписи. Замена hostname на «красивый» домен, неправильный регион или изменение подписанного значения могут нарушить проверку. Для просмотра метаданных используйте отдельно предусмотренный запрос с подходящей авторизацией.
Проследите путь ссылки от генератора до клиента: ответ API сайта, HTML-атрибут, письмо, перенаправление. Ищите обрезанную строку, дополнительное преобразование кодирования, потерянный параметр или изменение значения прокси. Не исправляйте адрес ручной перестановкой случайных частей: сравните его с тем, что действительно сформировал SDK.
Если недавно изменяли клиент скачивания, проверьте добавленные заголовки и X-Amz-SignedHeaders. Зафиксируйте также синхронизацию часов генератора. Ошибочное время подписи — отдельная причина; увеличение срока не заменяет корректные часы. Для повторного опыта сохраняйте прежние условия и меняйте только подтверждённо неверный компонент.
8. Отличайте продолжающуюся загрузку от нового запроса
По правилам использования presigned URL S3 проверяет истечение в момент HTTP-запроса. Начатая до границы срока загрузка может продолжаться после неё. Но если соединение оборвалось и клиент пытается начать новый запрос после истечения, старой ссылки уже недостаточно.
Докачка с Range — такой новый запрос, а не автоматическое продолжение прежнего разрешения. В учебном сценарии ссылка действует до 14:00: загрузка началась в 13:59, соединение оборвалось в 14:03, повтор начался в 14:04. Отказ повтора согласуется с истечением ссылки и не означает, что сервер обязан был остановить исходный поток ровно в 14:00.
После получения нового URL проверьте, что он относится к той же версии объекта, прежде чем соединять старую часть с новыми данными. Дополнительно учитывайте подписанные заголовки Range и If-Range, если они используются вашим клиентом. AWS требует подписать If-Range, если он присутствует в запросе вместе с Range, включённым в X-Amz-SignedHeaders. Сам факт выпуска нового адреса не подтверждает правильность докачки или целостность итогового файла.
Для воспроизведения достаточно небольшого тестового объекта и управляемой паузы. Не запускайте многогигабайтные скачивания только ради проверки срока. Если сценарий возобновления не проверяли, явно оставьте его отдельным пунктом приёмки.
9. Выдавайте новую ссылку после проверки доступа
Если причина подтверждена как истечение, пользователь должен вернуться в защищённый интерфейс сайта и запросить актуальный адрес. Сервер заново проверяет сессию, право на конкретный документ и его текущее состояние. Затем формирует ссылку штатным SDK с действующими credentials и подходящим сроком.
Приложению полезнее хранить внутреннюю связь с файлом, чем считать подписанный URL постоянным адресом документа. В письме можно вести пользователя на защищённую страницу получения файла, где доступ проверят в момент обращения. Такой маршрут требует продуманного интерфейса входа, но не заставляет сохранять одну временную ссылку на месяцы.
Не принимайте произвольный ключ S3 из браузера как разрешение на выпуск URL. Сопоставляйте запрошенный документ с серверными данными и правами пользователя. Иначе исправление просроченных ссылок создаст возможность получать доступ к чужим объектам через генератор.
Подписанная ссылка S3 по умолчанию не одноразовая: её можно использовать повторно, пока действуют условия доступа. Выход из личного кабинета сайта сам по себе не аннулирует уже выданную подпись S3. Поэтому срок выбирают по задаче и чувствительности документа, а требования к одноразовому использованию реализуют отдельным контролируемым механизмом приложения.
В собственном API выдачи можно возвращать вместе с адресом рассчитанное время окончания доступа, чтобы интерфейс своевременно предлагал запросить новую ссылку. Это поле вашей системы, а не дополнительное разрешение S3. Его значение должно учитывать известные ограничения и не обещать больше, чем генератор способен подтвердить. Таймер в браузере помогает пользователю, но решение о допуске нового запроса всё равно принимает хранилище.
10. Проверьте, откуда пользователю возвращается старый URL
Исправный генератор может не участвовать в повторном открытии страницы. Посмотрите, не сохранён ли готовый адрес в кеше HTML, ответе API, локальном состоянии интерфейса или старом письме. В таком случае обновление credentials на сервере не изменит уже сохранённую строку.
Учебный пример: страница с персональной ссылкой кешируется на 30 минут, а ссылка пригодна только десять минут. Пользователь открывает страницу через двадцать минут и получает устаревший адрес, хотя генератор сейчас способен создать новый. Проверка должна показывать время фактического выпуска ссылки, а не только время открытия страницы.
Не кешируйте персональные ответы выдачи ссылок как общедоступные. Проверьте правила хранения и повторного использования на каждом слое, особенно если общий кеш обслуживает разных пользователей. При обновлении интерфейса очищайте или заменяйте сохранённое значение по предусмотренной логике, а не предлагайте покупателю постоянно чистить весь браузер.
Различайте кеш самого файла и кеш адреса доступа. Уже скачанная или сохранённая разрешённым кешем копия не исчезает из-за окончания срока URL. Оценивать отказ нового запроса нужно по фактическому сетевому обращению, а не по тому, удалось ли открыть документ, оставшийся на устройстве после предыдущей загрузки.
11. Исключите утечки подписи в диагностике
AWS рекомендует относиться к подписанному URL как к временному средству доступа и скрывать подпись при журналировании. Проверьте журналы сайта, ошибки клиентской библиотеки, аналитику и системы поддержки: полный адрес может попадать туда автоматически.
Для расследования обычно достаточно внутреннего ID документа, времени подписи, заданного срока, безопасного идентификатора попытки и ошибки S3. Удаляйте подпись и токен из публичных материалов; при необходимости скрывайте всю query string и персональные части пути. Обезличивание должно происходить до отправки записи во внешнюю систему, а не после обнаруженной утечки.
Если рабочая ссылка уже раскрыта, действуйте по принятой процедуре доступа и оцените затронутые документы. Простая отправка владельцу новой ссылки не делает старую недействительной. При выборе ограничений учитывайте другие процессы, использующие ту же роль или объект: широкое изменение полномочий может остановить легитимные загрузки.
Не передавайте подписанные адреса приватных документов внешнему мониторингу. Для наблюдения за инфраструктурой используйте предназначенные для этого публичные адреса без секретных параметров. Пользовательскую выдачу закрытых файлов проверяйте отдельным согласованным сценарием внутри системы.
Полезен отдельный идентификатор выдачи, который не предоставляет доступа к файлу. По нему команда найдёт серверную запись и обезличенные параметры, не используя рабочую ссылку как номер обращения. Проверьте маскирование на тестовом адресе: оно должно сохраняться и в обычном журнале, и в сообщении об исключении, и в выгрузке для поддержки.
12. Подтвердите причину и результат исправления
Закрывайте задачу конкретным объяснением: истёк номинальный срок, закончилась сессия, сработала политика, изменился запрос, отсутствует объект или сайт повторно отдавал старый адрес. Формулировка «S3 не работает» скрывает различия и не помогает предотвратить повторение.
- Проверен небольшой тестовый объект и зафиксированы бакет, ключ и нужная версия.
- Рассчитаны срок URL и доступные ограничения credentials и политики.
- Свежая ссылка используется правильным методом и открывает ожидаемый документ.
- После истечения сайт предлагает получить новый доступ через авторизованный маршрут.
- Старый URL не возвращается из кеша; другой пользователь не получает персональную ссылку.
- Сценарий нового запроса после обрыва проверен отдельно от непрерывной загрузки.
- Журналы содержат полезные свидетельства, но не раскрывают рабочую подпись.
Назначьте владельцев генератора, прав хранилища и интерфейса выдачи. Сохраните короткую карточку с причиной, изменённым компонентом и проверкой после исправления. При следующем обращении она позволит быстро отличить ожидаемое истечение доступа от нового дефекта интеграции.
Подключите SiteGuard для внешнего наблюдения за HTTP-доступностью публичных страниц. Выпуск подписанных URL, проверка прав на документы и работа приватного скачивания остаются задачами вашей системы и её тестов.