title: CORS: PHP: Response to preflight request doesn't pass. Am allowing origin
body: <p>So I know there's a lot of CORS posts out there, and I'm just adding to them, but I can't find any with answers that help me out. So I'm building an angular 4 application that relies on my php api. Working locally it's fine, the moment I toss it up on the domain with the app at <code>app.example.com</code>, and the api at <code>api.example.com</code>, I can't get past my login, because I get the following error:</p>
  
  <blockquote>
    <p>XMLHttpRequest cannot load <a href="http://api.example.com/Account/Login" rel="noreferrer">http://api.example.com/Account/Login</a>.
    Response to preflight request doesn't pass access control check: No
    'Access-Control-Allow-Origin' header is present on the requested
    resource. Origin '<a href="http://app.example.com" rel="noreferrer">http://app.example.com</a>' is therefore not allowed
    access.</p>
  </blockquote>
  
  <p>My php code looks like this:</p>
  
  <pre><code>$http_origin = $_SERVER['HTTP_ORIGIN'];
  
  $allowed_domains = array(
      'http://example.com',
      'https://example.com',
      'http://app.example.com',
      'https://app.example.com',
      'http://www.example.com',
      'https://www.example.com'
  );
  
  if (in_array(strtolower($http_origin), $allowed_domains))
  {  
      // header("Access-Control-Allow-Origin: *");
      header("Access-Control-Allow-Origin: $http_origin");
      header('Access-Control-Allow-Credentials: true');
      header('Access-Control-Max-Age: 86400');
  }
  
  // Access-Control headers are received during OPTIONS requests
  if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {
          header("Access-Control-Allow-Methods: GET, POST, OPTIONS");
          header("Access-Control-Allow-Headers: Authorization, Content-Type,Accept, Origin");
      exit(0);
  }
  </code></pre>
  
  <p>My Angular post looks like this:</p>
  
  <pre><code>public login(login: Login): Observable&lt;LoginResponse&gt; {
      let headers = new Headers();
      headers.append('Content-Type', 'application/x-www-form-urlencoded');
      headers.append('Authorization', 'Basic ' + btoa(login.Username + ':' + login.Password));
      return  this.http.post(this.apiBaseUrl + '/Account/Login', "grant_type=client_credentials", { headers: headers })
          .map(response =&gt; {
              // code
          });
  }
  </code></pre>
  
  <p>If I run the request through postman, which doesn't bother with CORS, I get:</p>
  
  <pre><code>{ "error": "invalid_client", "error_description": "Client credentials were not found in the headers or body" }
  </code></pre>
  
  <p>I've tried setting origin to '<code>*</code>' just to test and see if that was the core of the issue, and it still fails the same way.</p>
  
  <p><strong><em>Edit</em></strong>
  Just updating from information below. Changing casing in headers had no effect, and pulling the code out of their if statements had no effect.</p>
  
  <p>I debugged the php by telling my live app to go to my local api, and the php is working as expected. It's setting the headers and making it into each of the if statements.</p>
  
  <p><strong><em>Edit take 2</em></strong>
  I could really use some help on this one, if someone has any ideas, I'd really appreciate it.</p>
  
  <p><strong><em>Edit take 3</em></strong>
  If I set all the header stuff in my .htaccess rather than my php, it lets me through. However, now I'm stuck on the error listed above that I always get when using postman, however now it's while using the actual site. </p>
  
  <p><code>{"error":"invalid_client","error_description":"Client credentials were not found in the headers or body"}</code></p>
  
  <p>My response headers are like so</p>
  
  <pre><code>Access-Control-Allow-Credentials:true
  Access-Control-Allow-Headers:authorization, content-type, accept, origin
  Access-Control-Allow-Methods:GET, POST, OPTIONS
  Access-Control-Allow-Origin:*
  </code></pre>
  
  <p>I'll be changing it from * to only my domains once I have it working. But for now i'll leave it as *.</p>
  
  <p><strong>My headers as requested.</strong></p>
  
  <p><a href="https://i.stack.imgur.com/QjsYl.png" rel="noreferrer"><img src="https://i.stack.imgur.com/QjsYl.png" alt="Headers for failed request"></a></p>