CakePHP2: CORS Preflight issues with JWT Auth
<p>I'm building an Ionic 1 app that talks to a REST API implemented in CakePHP 2.8, using <a href="https://en.wikipedia.org/wiki/JSON_Web_Token" rel="nofollow noreferrer">JSON Web Tokens (JWT)</a> for auth.</p>

<p>In an unauthorized state, my app is able to make GET / POST requests to the server with no issue. However, once I have authenticated and my app is sending a <code>authToken</code> header along with every request, Angular automatically sends an <code>OPTIONS</code> preflight request first.</p>

<p>This is where the problem starts. Because the automatic preflight request does not have the <code>authToken</code> header set, and because the API endpoint requires authorization, CakePHP responds with a 302 FOUND redirect to <code>/login</code>. The app (or browser, at this testing phase) considers this unsafe, and never goes on to make the proper request.</p>

<p><strong>My question:</strong> How can I get CakePHP to respond appropriately to preflight OPTIONS requests so that AngularJS knows it can safely send a custom header to a cross-domain server?</p>

<p>Per <a href="https://stackoverflow.com/questions/8685678/cors-how-do-preflight-an-httprequest">this question</a>, this is what needs to happen:</p>

<p>Request headers:</p>

<pre><code>Origin: http://yourdomain.com
Access-Control-Request-Method: POST
Access-Control-Request-Headers: X-Custom-Header
</code></pre>

<p>Response headers:</p>

<pre><code>Access-Control-Allow-Origin: http://yourdomain.com // Same as origin above
Access-Control-Allow-Methods: GET, POST
Access-Control-Allow-Headers: X-Custom-Header
</code></pre>

<p><strong>Things I've tried:</strong></p>

<p>-Setting <code>.htaccess</code> to always respond to <code>OPTIONS</code> requests with a <code>200</code>. I get a 200 response, but the response says "your server is misconfigured" and, because it doesn't have the proper headers set, the real <code>$http</code> request never goes through.</p>

<p>-Getting CakePHP to always respond a certain way to <code>OPTIONS</code> requests. The issue here is getting Cake to skip authorization, skip trying to run the controller action, and send back a HTTP 200 response with the proper headers set.</p>

<pre><code>    // AppController::beforeFilter();
    if($this-&gt;request-&gt;is("options")){
        // Send the appropriate response based on the request
    }
</code></pre>

<p>For the curious, here are the headers that get exchanged in the course of a failed <code>$http</code> request:</p>

<pre><code>GENERAL:
Request URL:https://api.example.com/rest_users/profile.json
Request Method:OPTIONS
Status Code:302 Found
Remote Address:x.x.x.x:443

REQUEST HEADERS:
Accept:*/*
Accept-Encoding:gzip, deflate, sdch, br
Accept-Language:en-US
Access-Control-Request-Headers:authtoken
Access-Control-Request-Method:GET
Cache-Control:no-cache
Connection:keep-alive
DNT:1
Host:api.example.com
Origin:http://x.x.x.x:8100
Pragma:no-cache
Referer:http://x.x.x.x:8100/
User-Agent:Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.95 Safari/537.36


RESPONSE HEADERS:
Access-Control-Allow-Headers:Content-Type, x-xsrf-token
Access-Control-Allow-Methods:*
Access-Control-Allow-Origin:*
Access-Control-Max-Age:172800
Connection:Keep-Alive
Content-Encoding:gzip
Content-Length:20
Content-Type:text/html; charset=UTF-8
Date:Thu, 29 Dec 2016 18:51:30 GMT
Keep-Alive:timeout=15, max=99
Location:https://api.example.com/login
Server:Apache/2.2.15 (CentOS)
Vary:Accept-Encoding
X-Powered-By:PHP/5.3.3
</code></pre>