Вкратце
Чтобы сохранить загруженные носители (объекты S3) частными для всех клиентов в моей мультитенантной системе, я реализовал развертывание CloudND CDN и настроил его (и его исходную корзину S3) дляпринудительное использование подписанных URL-адресов для получения любого из объектов.
Метод
Сначала пользователь проходит проверку подлинности через мою систему, а затем генерируется подписанный URL-адрес и возвращается к ним с помощью AWS.CloudFront.Signer.getSignedUrl()
метод предоставлен AWS JS SDK .чтобы они могли сделать запрос к CF / S3 для загрузки объекта (изображение, PDF, docx и т. д.).Довольно стандартные вещи.
Проблема
Вышеуказанный метод работает в 95% случаев.Пользователь получает подписанный URL-адрес из моей системы, а затем, когда он делает XHR, чтобы ПОЛУЧИТЬ объект, который он извлекает, просто отлично.
Но в 5% случаев выдается 403 с ошибкой CORS о том, что клиентorigin is not allowed by Access-Control-Allow-Origin
.
Эта ошибка (ошибка) была подтверждена во всех средах: localhost, dev.myapp.com, prod.myapp.ком.И на всех платформах / браузерах.
Существует так мало рифмы или причины, по которой я начинаю думать, что это ошибка AWS (они случаются время от времени).
Контрольный список отладки до сих пор
Я с ума схожу уже несколько дней, пытаясь выяснить это.Вот что я пытался сделать до сих пор:
Вы пробовали другой браузер / платформу?
Да.Эта проблема присутствует во всех клиентских версиях, браузерах (и версиях) и на всех платформах.
Правильно ли настроен ваш S3 Bucket для CORS?
Да.Это широко открыто на самом деле.Я даже установил <MaxAgeSeconds>0</MaxAgeSeconds>
, чтобы предотвратить кэширование любых предварительных запросов OPTIONS
клиента:
Срок действия подписанного URL-адреса истек?
Нет.Срок действия всех подписанных URL истекает через 24 часа после генерации.Эта проблема обнаруживается даже через несколько секунд после создания любого подписанного URL-адреса.
Есть ли проблема с методом, используемым для создания подписанных URL-адресов?
Маловероятно.Я просто использую метод AWS.CloudFront.Signer.getSignedUrl()
их JS SDK.Подписанные URL-адреса do работают большую часть времени, поэтому может показаться очень странным, что это будет проблемой в процессе подписания.Кроме того, эта ошибка явно является ошибкой CORS, а не ошибкой совпадения подписи.
Это проблема часового пояса / часов сервера?
Нет.Система действительно обслуживает пользователей во многих часовых поясах, но эта теория оказалась ложной, учитывая, что все подписанные URL-адреса генерируются на стороне сервера.Часовой пояс клиента не имеет значения, он получает подписанный URL-адрес в течение 24 часов с момента генерации, независимо от того, в каком TZ он находится.
Настроен ли ваш дистрибутив CFправильно?
Да, насколько я могу разобрать, следуя нескольким руководствам AWS , учебникам , документам и прочим .
Вот скриншот для краткости.Вы можете видеть, что я полностью отключил кеширование, пытаясь исключить это как причину:
Вы видите эту ошибку для всех типов пантомимы?
Нет.Эта ошибка не была обнаружена ни для каких изображений, аудио или видео файлов (объектов).После большого количества уже выполненных испытаний эта ошибка появляется только при попытке получить документ или файл PDF (.doc, .docx, .pdf).Это привело меня к мысли, что это просто ошибка несоответствия заголовка Accept
: клиент отправлял XHR с заголовком Accept: pdf
, но на самом деле подпись была сгенерирована для Accept: application/pdf
.Я еще не смог полностью исключить это какпричина.Но это маловероятно, учитывая, что ошибки периодически.Таким образом, если бы это была проблема несоответствия заголовка Accept
, то это должно быть ошибкой каждый раз.
Кроме того, XHR отправляет Accept: */*
, поэтому весьма маловероятно, что именно в этом проблема.
Вопрос
Я действительно ударил стену по этому.Кто-нибудь может увидеть, что мне здесь не хватает?Лучшее, что я могу придумать, это то, что это какая-то проблема с выбором времени.Что за проблема с синхронизацией, или если это вообще проблема с синхронизацией, я еще не выяснил.
Заранее благодарен за любую помощь.