Подтвердить что ты не робот

Избегайте предваротельных запросов OPTIONS с CORS

Я создаю приложение Angular, которое взаимодействует с API, созданным с помощью ASP.NET Web API 2. Я использую базовую проверку подлинности, отправив заголовок Authorization с каждым запросом, который требует аутентификации:

Angular фрагмент:

$http.defaults.headers.common['Authorization'] = authHeader;

Запрос:

Accept:application/json, text/javascript
Accept-Encoding:gzip, deflate, sdch
Accept-Language:en-US,en;q=0.8
Access-Control-Max-Age:1728000
Authorization:Basic [base64 encoded credential couplet here]
Connection:keep-alive
DNT:1
Host: blah.com
Origin:http://localhost:9000
Referer:http://localhost:9000/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_3) AppleWebKit/53

Все это работает OKAY, но с запросом GET или POST отправляется запрос preflight OPTIONS. Это существенно влияет на воспринимаемую скорость приложения. Я много читал в CORS "Простые запросы", и кажется, что во избежание страшного предполетного запроса OPTIONS следует избегать добавления каких-либо пользовательских заголовков в мои запросы. Я пробовал много других вещей, таких как отправка Content-Type из text/plain, но кажется, что заголовок авторизации - это то, что нарушает требование "Простой запрос" CORS.

Похоже, мне, возможно, придется переместить API, чтобы использовать аутентификацию/авторизацию на основе токенов. Чтобы избежать предпродажных запросов, кажется, что мне нужно будет поместить токен в строку запроса. Это нормально, так как это всего лишь небольшое внутреннее веб-приложение, доступ к которому будет доступно только нескольким пользователям. Я намерен реализовать кэширование ответов контроллера. Поскольку каждый запрос к действию контроллера будет иметь другой токен в querystring на основе текущего пользователя, прошедшего проверку подлинности, будет ли этот кеширование бесполезным?

Итак:

  • Как избежать запросов перед полетом (используя, если это возможно, пользовательские заголовки авторизации)
  • Если 1.) невозможно, и я перехожу к auth на основе токенов, я не смогу кэшировать ответы API для действий контроллера.
  • Каковы наиболее широко используемые методы, позволяющие избежать предпродажных запросов, а также безопасных пользователей?

nb Я знаю, что есть несколько других потоков на SO и в других местах в Интернете относительно этого, но ни один из них не дает окончательного ответа о том, можно ли избежать предполетных запросов для GET и POST при использовании пользовательских заголовков HTTP.

4b9b3361

Ответ 1

Я думаю, что этот пост (Как применять кеш-память CORS для всего домена) в значительной степени говорит об этом - вы мало что можете сделать об этом

Одним простым решением является добавление обратного прокси-сервера в прокси-сервер, обслуживающий ваше приложение angular (например, nginx) для маршрутизации вызовов RESTful через один и тот же домен, например. appdomain.com/api → apidomain.com.

Ответ 2

Другое решение, которое, кажется, работает нормально для меня. Вместо того, чтобы настраивать прокси-сервер и нужно перенаправить его в тот же домен, можно вернуть запрос предварительной проверки непосредственно из nginx и, следовательно, сократить время, требуемое запросом предварительной проверки, до нескольких миллисекунд.

Вот простой фрагмент, который можно использовать с nginx.

 location / {
    if ($request_method = 'OPTIONS') {
        add_header 'Access-Control-Allow-Origin' '*';
        add_header 'Access-Control-Allow-Credentials' 'true';
        add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS';
        add_header 'Access-Control-Allow-Headers' 'Content-Type, Authorization';
        add_header 'Access-Control-Max-Age' 1728000;
        add_header 'Content-Type' 'text/plain charset=UTF-8';
        add_header 'Content-Length' 0;
        return 204;
     }
}

Как только запрос предварительной проверки будет успешным, тогда можно просто добавить "Access-Control-Allow-Origin" и другие необходимые материалы в запросы "GET", "POST" и т.д.