4

Updated code and the cause further down


I'm building a client side application that has the capabilities to talk to Phil Sturgeons code igniter rest application.

The issue is when trying to request the login method I am prompted by OPTIONS http://site/api/login 403 (Forbidden) and OPTIONS http://site/api/login Invalid HTTP status code 403.

I've enabled CORS both on server and apache level in hopes it might change the response messages. In application/config/config.php

header('Access-Control-Allow-Origin: *');
header('Access-Control-Allow-Methods: GET, POST, PUT, OPTIONS');
header('Access-Control-Allow-Headers: X-API-KEY, X-AUTH-TOKEN');
// header('Access-Control-Allow-Methods: OPTIONS, true, 200'); <- tried this also

On Apache level in httpd.conf

Header always set Access-Control-Allow-Origin "*"                   
Header always set Access-Control-Allow-Methods "POST, GET, OPTIONS, PUT, DELETE"

The jQuery code, I've commented out previous approaches on sending different headers. If X-API-KEY isn't specified it will return the appropriate error {"status":false,"error":"Invalid API Key."}

$.ajax({
    type: "POST",
    url: "http://site/api/login",
    data: {data : encrypted_login},
    headers: {"X-API-KEY": "_API_KEY_"},
    // headers: {"X-API-KEY": "_API_KEY_", "Content-Type":  "application/x-www-form-urlencoded"},
    // beforeSend: function( xhr ) {
        // xhr.overrideMimeType( "application/x-www-form-urlencoded;" );
        // xhr.setRequestHeader('X-API-KEY', '_API_KEY_');
        // xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded;');
        // Tried different Content-Types to try avoid the pre-flight call
    // },
    // crossDomain: true,
    // dataType: 'json',
    success: function(data) {
       console.log('success' + data); // show response from the php script.
    },
    error: function(XMLHttpRequest, textStatus, errorThrown){
        alert(errorThrown); // throws empty
    },
    fail: function(data) {
        console.log('fail login : ',data);
    }
});

With the newest update of the rest library support for OPTION, PATCH and HEAD has been added. I wrote a method that would accomodate the login options call that always returns 200. Which unfortunately didn't change the situation.

function login_options(){
    $this->response(array('response' => 'Hello World!'), 200);
}

Note: When using POSTMAN chrome extension all calls including that to login_options works perfectly.

Edit: Has something to do with Phil Sturgeons library denying it, the root of the site accepts pre-flight requests. Using 3.0.0-pre build version

Edit: Has to do with passing headers to the request. Without this and API keys disabled it works.




Update:

The problem is due to using virtual host names. Why this is happening I'm unsure, I've tested with 3 blank instalments of Phil Sturgeons rest server on 2 different machines and was able to replicate the problem on all of them.

It didn't matter how I had setup the virtual host, I tried these two approaches.

My httpd-vhosts.conf

<VirtualHost *>
DocumentRoot "/Users/admin/Sites/rest_library"
ServerName rest_library
ErrorLog "/private/var/log/apache2/rest_library-error_log"
CustomLog "/private/var/log/apache2/rest_library-access_log" common
<Directory "/Users/admin/Sites">
    AllowOverride All
    Options Indexes FollowSymLinks MultiViews
    Order allow,deny
    Allow from all
</Directory>
</VirtualHost>

Works mates httpd-vhosts.conf

<VirtualHost *:80>
  ServerName restserver
  DocumentRoot "/Users/admin/Sites/codeigniter-restserver"
  DirectoryIndex index.php
  <Directory "/Users/admin/Sites/codeigniter-restserver">
    AllowOverride All
    Allow from All
  </Directory>
</VirtualHost>

To get around this I have to reference everything as http://localhost/rest_library/api/ instead. This also happens on servers with CNAMES, haven't tested top level site yet. Using the exact same code I was able to get the non virtual host one working while the one with a virtual host was failing.

Also because you can't set Access-Control-Allow-Headers as a wildcard while Access-Control-Allow-Credentials is set I used a less reliable method to get around

header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']);
Bankzilla
  • 2,086
  • 3
  • 25
  • 52

2 Answers2

0

Try to change - to _ in header names.

https://github.com/philsturgeon/codeigniter-restserver/blob/4fb294b45607d394871a9d1cb9828e789195826a/application/libraries/REST_Controller.php#L681

Greg
  • 698
  • 4
  • 11
  • Unfortunately it's still the same. I renamed it to `X_API_KEY` and get stopped on the preflight OPTIONS request. Thanks for the suggestion, wasn't something I had actually tried yet! – Bankzilla Feb 12 '14 at 20:56
  • So you are no longer getting "Invalid API Key." ? – Greg Feb 12 '14 at 21:44
  • Nope getting `403 Invalid HTTP Status`. We've worked out the issue but trying to find a solution to fixing it before adding it as an answer. [Also as of Apache 2.4 underscores in headers are silently dropped.](http://httpd.apache.org/docs/trunk/new_features_2_4.html) – Bankzilla Feb 12 '14 at 22:03
  • Try to send empty response body in `function login_options(){`. Also try different browser. – Greg Feb 12 '14 at 22:13
  • Doesn't even reach the construct. I've tried on safari, firefox and chrome – Bankzilla Feb 12 '14 at 22:27
0

I found an answer in another Stack Overflow thread and it works!

You need to detect method and if it's OPTIONS then exit php by die()!

Credit: https://stackoverflow.com/a/19310265/3679394

Community
  • 1
  • 1
Kanad Godse
  • 309
  • 1
  • 6