I am building an Angular app that interacts with an API built with ASP.NET Web API 2. I am using Basic Authentication by sending an Authorization
header with each request that requires authentication:
Angular snippet:
$http.defaults.headers.common['Authorization'] = authHeader;
Request:
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
This all works OKAY, but a preflight OPTIONS
request is sent with every GET
or POST
request. This is majorly impacting the perceived speed of the application. I have done lots of reading on CORS "Simple Requests" and it seems that in order to avoid the dreaded preflight OPTIONS
request is to avoid adding any custom headers in my requests. I've tried lots of other stuff like sending a Content-Type
of text/plain
, but it seems that the Authorization header is the thing that is violating the CORS "Simple request" requirement.
So it seems that I may have to move the API over to use token based authentication/authorization. In order to avoid preflight requests, it seems that I will need to place the token in the query string. This is okay as it is only a small internal web app which will only be accessed by a couple of users anyway. I intend to implement caching on controller responses. As each request to an controller action will have a different token in the querystring based on the currently authenticated user, will this render cacheing useless?
So:
1.)
is not possible, and I move to token based auth, will I be unable to cache API responses for controller actionsn.b I know there are a couple of other threads on SO and elsewhere on the web regarding this, but none of them tend to provide a definitive answer on whether it is possible to avoid preflight requests for GET
s and POST
s when using custom HTTP
authorization headers.
The simplest way to prevent this is to set the Content-Type to be text/plain in your case. application/x-www-form-urlencoded & multipart/form-data Content-Types are also acceptable, but you'll of course need to format your request payload appropriately.
A CORS preflight request is a CORS request that checks to see if the CORS protocol is understood and a server is aware using specific methods and headers. It is an OPTIONS request, using three HTTP request headers: Access-Control-Request-Method , Access-Control-Request-Headers , and the Origin header.
This opt-in is the preflight request. So GET/POST requests without any custom headers don't need a preflight, since these requests were already possible before CORS. But any request with custom headers, or PUT/DELETE requests, do need a preflight, since these are new to the CORS spec.
Check for the existence of these essential information present in a preflight request: The request's HTTP method is OPTIONS. It has an Origin header. It has an Access-Control-Request-Method header, indicating what's the actual method it's trying to use to consume your service/resource.
I think this post (How to apply CORS preflight cache to an entire domain) pretty much says it all - there is not much you can do about this
The one simple solution is to add a reverse proxy to the proxy/webserver serving your angular app (e.g. nginx) to route your RESTful calls via the same domain, e.g. appdomain.com/api --> apidomain.com.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With