javascript - How to handle custom headers with CORS Pre-flight request? AJAX - CodeIgniter -


i'm working codeigniter , restfull api structure web server private api.

i've started using cors per requirements framework i'm using.

working jquery, can see 2 requests sent, first 1 option type - expected - without custom header (x-api-key security, default in codeigniter restful api).

i receive invalid api key error message shown in picture. right after proper request being sent correct headers in meantime, first requests triggered .fail() function handle errors.

first pre flight call trigger invalid api key since can't pass x-api-key custom header in call the normal call working fine

what's best practice handle scenario ? ajax request smoothly handle first preflight option request without triggering error on app today, normal call custom headers per how cors works , execute success call without never triggering error call in first preflight request ?

triggerfriendswall: function() {         //get location             var options = {                 timeout: 30000,                 enablehighaccuracy: true,                 maximumage: 90000             };              //we need check if user has disabled geolocation, in case makes app crashes ! (from cordova.js 1097)             var position = json.parse(localstorage.getitem("position"));              if (position == "" || position == null || position == "null" || typeof position == "undefined" ) {                 // in case have never set location , user has enabled it.                 navigator.geolocation.getcurrentposition( function(position) {                     home.friendswall(position);                 }, function(error) {                     common.handle_errors(error, home.friendswall);                 }, options);             } else {                 // in case, user has disabled geolocatoin !                 common.handle_errors(false, home.friendswall);             } },   friendswall: function(position) {      $.when(userdao.getusersnearby(position.coords.latitude, position.coords.longitude, home.usr_radius, home.usr_limit, home.usr_offset))                 .done(function(response) {                    // stuff     }) }   getusersnearby: function(lat, lng, radius, limit, offset) {             var key = localstorage.getitem("key");              return $.ajax({                 type: "get",                 url: config.server_url + 'user/userssurrounding',                 headers: {                     'x-api-key': key                 },                 data: {                     lat: lat,                     lng: lng,                     radius: radius,                     limit: limit,                     offset: offset                 },                 datatype: 'json'             });         }, 

many

edit: constructor associated controllers ( controller extend single controller construct method : )

public function __construct() {      header('access-control-allow-origin: *');     header("access-control-allow-headers: x-api-key, origin, x-requested-with, content-type, accept, access-control-request-method");     header("access-control-allow-methods: get, post, options, put, delete");     $method = $_server['request_method'];     if($method == "options") {         die();     }      parent::__construct();     // $this->load->model('admin_model');     $this->load->library('session');     $this->load->library('key'); } 

are using access-control-allow-headers?

used in response preflight request indicate http headers can used when making actual request.

try adding following header preflight code.

header("access-control-allow-headers: content-type, origin, accept, x-api-key"); 

i recall having similar issues, seem recall of being browser specific too...

if helps here snippet code know works:

// cors , other headers.  make sure file not cached (as happens example on ios devices) header("expires: mon, 26 jul 1997 05:00:00 gmt"); header("last-modified: " . gmdate("d, d m y h:i:s") . " gmt"); header("cache-control: no-store, no-cache, must-revalidate"); header("cache-control: post-check=0, pre-check=0", false); header("pragma: no-cache"); header('access-control-allow-origin: *'); header('access-control-allow-methods: post'); header('access-control-max-age: ' . cors_auth_max_age);  //cors preflight if (isset($_server['request_method']) && $_server['request_method'] == 'options') {      header("access-control-allow-headers: content-type, origin, accept, x-app-sig");      $acrh = explode(',', strtolower($headers['access-control-request-headers']));     foreach ($acrh $k => $v) {         $acrh[$k] = trim($v);     }      if (! isset($headers['access-control-request-headers']) || ! in_array('x-app-sig', $acrh)) {         _log($h, '*** bad preflight!' . php_eol . print_r($headers, true) . php_eol . print_r($_request, true));         header("http/1.1 401 unauthorized");         exit; //->     }      _log($h, '+++ successful preflight.' . php_eol . print_r($headers, true) . php_eol . print_r($_request, true));     exit; //-> }  //now past preflight.  actual auth happens here, check signature post payload. 

update: ok, think better understand question now. posted bit more code. first off, yes, doing same thing there. check preflight tried white-list should have in terms of headers.

i think part missing preflight should/will not have custom header trying send. see answer here: how send custom header in cross-domain (cors) xmlhttprequest?). check access-control-request-headers: sent preflight, should not check actual header being present on call.

sounds need move little of code around server side - make preflight pretty vanilla , dumb, actual auth or checking of custom headers after successful preflight.

i use hmac signature sent payload myself authenticate things after preflight. check custom x-app-sig supplied , expect though redundant.


Comments

Popular posts from this blog

PHP DOM loadHTML() method unusual warning -

python - How to create jsonb index using GIN on SQLAlchemy? -

c# - TransactionScope not rolling back although no complete() is called -