Handle the OPTIONS preflight check on CORS requests

I’m building an app with a YII2 back-end and vuejs front end. While developing, the front end is running on localhost:3000 but the PHP/Apache server is running on my normal port 80 at appname.local host name.

I finally got this working with CSRF (the withCredentials header on the front end was missing and that messed my csrf cookie stuff) but before I ran into that, I was hitting issues on my login form because chrome would actually send a secret OPTIONS request to the back end to get the ACCEPT headers to verify the CORS security stuff. The problem is that when OPTIONS is used, the post data was not included with the request so the login form threw a 400 HTTP error (by design) since the login failed. The 400+ error codes are a deal breaker for the OPTIONS preflight check so the browser just gives up and puts a CORS error in the console.

To work around this issue I finally just setup an “on beforeAction” in my web.php config file to set up a global controller beforeAction to basically just respond with a 200 OK and end the app immediately for all OPTIONS requests, after setting the required CORS headers.

Is there a better way to deal with this? I don’t want to have to manually deal with OPTIONS in all of my controller actions so I’m not sure there is… I just want to see if anyone else with more YII and CORS experience knows a better way.

I did read that there might be a way using the Content-Type header on the front end that can avoid the preflight check but I have not looked into that yet so I might mess around with that when I have some time.

Luckily this is is a personal project so I’m not really on a project budget lol…

Also I just remembered that there is a way to set up a NUXT api proxy that completely works around this problem so now I want to blow my brains out for wasting a bunch time all because I forgot this was a thing ha ha ha… Still curious on my question though, in case I need to deal with something similar in a non-dev / production environment…

I have all the developments with Firefox, Chrome is unstable in execution and even more so when they are high volume records, What operating system are you working with? For a stable project, do you have Linux as a base?

I’m on windows… but the question wasn’t really related to chrome or anything like that. I just wanted to see if anyone had experience with handling API requests that need to support CORS and how they end up handling the possible OPTIONS preflight check request. I wasn’t sure if just intercepting the OPTIONS request in my global “on beforeAction” handler and returning an empty OK/200 response with the requisite CORS headers was the best option I have.

The problem came up because my login controller action is configured to only accept POST requests so at first the CORS was failing because the server was responding with a 400 to the OPTIONS request due to the method not being explicitly listed as supported. Then, even after adding OPTIONS t the method list for the action, CORS was failing because the OPTIONS request does not include the post data for the login, so my login auth code was failing and throwing a 400 request (which is by design).

The only “work around” I came up with was to test the _SERVER[“REQUEST_METHOD”] value for OPTIONS and force the response to be OK/200 before the controller had a chance to fail the request.

In lieu of having to do this for every single controller action I just configured it globally.

So I’m just looking for confirmation this is “best practices” for this type of thing or if there is a better or more “official” way of handling this. Like, does YII have a “CORS Enabled” mode that I just dont know about or something like that?

Hi. Did you check the guide on the topic? https://www.yiiframework.com/doc/guide/2.0/en/rest-controllers#cors

[…] Also authentication has to be disabled for the CORS Preflight requests so that a browser can safely determine whether a request can be made beforehand without the need for sending authentication credentials.

2 Likes

OMG TY! I don’t know what I was searching to not find this but this is exactly what I was looking for. Thank you :slight_smile:

1 Like

This post was flagged by the community and is temporarily hidden.