Избегайте предваротельных запросов 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
.
Ответы
Ответ 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" и т.д.