Запрос 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.

Пока браузеры не догонят, единственно возможными вариантами могут быть один или их комбинация:

  1. Выпуск перенаправлений только для простых запросов.
  2. Создайте редирект 305 с вашим собственным URL в Location Заголовок как "прокси". Будьте готовы к ограниченной поддержке браузера, так как 305 устарела.
  3. Сделайте фальшивый "редирект":
    • вернуть HTML с meta refresh и / или Javascript Location менять.
    • возврат HTML, который имеет заполнение области просмотра iframe с целью перенаправления в качестве источника iframe.
    • отобразить ссылку, по которой пользователь должен щелкнуть, чтобы получить доступ к контенту.
Другие вопросы по тегам