Запрос CORS с Preflight и перенаправлением: запрещено. Обходные?
Я разрабатываю API, который позволяет пользователю проходить аутентификацию (используя токены) и который содержит перенаправления в пределах одного домена. Теперь для неаутентифицированного запроса к конечной точке, которая возвращает 303,
GET /documents/123 --> 303 redirect to `/documents/abc`
GET /documents/abc --> 200
все работает хорошо.
Давайте сделаем аутентифицированный запрос к той же конечной точке, где Authorization
Заголовок отправлен. Это делает запрос предварительным запросом, а браузер выполняет предварительный просмотр OPTIONS
запрос, т.е.
OPTIONS /documents/123 --> 204 (everything okay, please proceed)
GET /documents/123 --> 303 redirect to `/documents/abc`
На данный момент, вместо GET
фактический ресурс в /documents/abc
, браузер дает
XMLHttpRequest cannot load http://localhost:8000/people/username/nschloe.
The request was redirected to 'http://localhost:8000/people/YDHa-B2FhMie',
which is disallowed for cross-origin requests that require preflight.
Такое поведение соответствует стандарту:
7.1.5 Запрос перекрестного происхождения с предварительной проверкой
Если ответ имеет код состояния HTTP, который не находится в диапазоне 2xx
Применить шаги ошибки сети.
Похоже, это означает, что нельзя выполнять перенаправления для аутентифицированных ресурсов, даже если перенаправление находится в том же домене (localhost
).
Может ли это быть правдой? Есть ли общий обходной путь?
1 ответ
Первоначальный стандарт не допускает перенаправления после успешной предварительной проверки CORS. Цитирование § 7.1.5.3:
Это фактический запрос. Примените шаги создания запроса и соблюдайте приведенные ниже правила запроса при выполнении запроса.
- Если ответ имеет код состояния HTTP 301, 302, 303, 307 или 308, выполните шаги кеша и ошибки сети.
Благодаря вашим усилиям (спасибо!) 4 августа стандарт был обновлен, чтобы разрешить перенаправление после успешной предварительной проверки CORS.
Пока браузеры не догонят, единственно возможными вариантами могут быть один или их комбинация:
- Выпуск перенаправлений только для простых запросов.
- Создайте редирект 305 с вашим собственным URL в
Location
Заголовок как "прокси". Будьте готовы к ограниченной поддержке браузера, так как 305 устарела. - Сделайте фальшивый "редирект":
- вернуть HTML с
meta refresh
и / или JavascriptLocation
менять. - возврат HTML, который имеет заполнение области просмотра
iframe
с целью перенаправления в качестве источника iframe. - отобразить ссылку, по которой пользователь должен щелкнуть, чтобы получить доступ к контенту.
- вернуть HTML с