Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

AngularJS $http, CORS and http authentication

Tags:

angularjs

cors

Because using CORS and http authentication with AngularJS can be tricky I edited the question to share one learned lesson. First I want to thank igorzg. His answer helped me a lot. The scenario is the following: You want to send POST request to a different domain with AngularJS $http service. There are several tricky things to be aware of when getting AngularJS and the server setup.

First: In your application config you must allow cross domain call

/**  *  Cors usage example.   *  @author Georgi Naumov  *  [email protected] for contacts and   *  suggestions.   **/  app.config(function($httpProvider) {     //Enable cross domain calls     $httpProvider.defaults.useXDomain = true; }); 

Second: You must specify withCredentials: true and username and password into request.

 /**   *  Cors usage example.    *  @author Georgi Naumov   *  [email protected] for contacts and    *  suggestions.    **/     $http({         url: 'url of remote service',         method: "POST",         data: JSON.stringify(requestData),         withCredentials: true,         headers: {             'Authorization': 'Basic bashe64usename:password'         }     }); 

Тhird: Server setup. You must provide:

/**  *  Cors usage example.   *  @author Georgi Naumov  *  [email protected] for contacts and   *  suggestions.   **/  header("Access-Control-Allow-Credentials: true"); header("Access-Control-Allow-Origin: http://url.com:8080"); header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS"); header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization"); 

For every request. When you receive OPTION you must pass:

/**  *  Cors usage example.   *  @author Georgi Naumov  *  [email protected] for contacts and   *  suggestions.   **/  if($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {    header( "HTTP/1.1 200 OK" );    exit(); } 

HTTP authentication and everything else comes after that.

Here is complete example of usage of server side with php.

<?php /**  *  Cors usage example.   *  @author Georgi Naumov  *  [email protected] for contacts and   *  suggestions.   **/  header("Access-Control-Allow-Credentials: true"); header("Access-Control-Allow-Origin: http://url:8080"); header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS"); header("Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept, Authorization");  if($_SERVER['REQUEST_METHOD'] == 'OPTIONS') {    header( "HTTP/1.1 200 OK" );    exit(); }   $realm = 'Restricted area';  $password = 'somepassword';  $users = array('someusername' => $password);   if (isset($_SERVER['PHP_AUTH_USER']) == false ||  isset($_SERVER['PHP_AUTH_PW']) == false) {     header('WWW-Authenticate: Basic realm="My Realm"');      die('Not authorised'); }  if (isset($users[$_SERVER['PHP_AUTH_USER']]) && $users[$_SERVER['PHP_AUTH_USER']] == $password)  {     header( "HTTP/1.1 200 OK" );     echo 'You are logged in!' ;     exit(); } ?> 

There is an article on my blog about this issue which can be seen here.

like image 738
Georgi Naumov Avatar asked Jan 30 '14 11:01

Georgi Naumov


1 Answers

No you don't have to put credentials, You have to put headers on client side eg:

 $http({         url: 'url of service',         method: "POST",         data: {test :  name },         withCredentials: true,         headers: {                     'Content-Type': 'application/json; charset=utf-8'         }     }); 

And and on server side you have to put headers to this is example for nodejs:

/**  * On all requests add headers  */ app.all('*', function(req, res,next) {       /**      * Response settings      * @type {Object}      */     var responseSettings = {         "AccessControlAllowOrigin": req.headers.origin,         "AccessControlAllowHeaders": "Content-Type,X-CSRF-Token, X-Requested-With, Accept, Accept-Version, Content-Length, Content-MD5,  Date, X-Api-Version, X-File-Name",         "AccessControlAllowMethods": "POST, GET, PUT, DELETE, OPTIONS",         "AccessControlAllowCredentials": true     };      /**      * Headers      */     res.header("Access-Control-Allow-Credentials", responseSettings.AccessControlAllowCredentials);     res.header("Access-Control-Allow-Origin",  responseSettings.AccessControlAllowOrigin);     res.header("Access-Control-Allow-Headers", (req.headers['access-control-request-headers']) ? req.headers['access-control-request-headers'] : "x-requested-with");     res.header("Access-Control-Allow-Methods", (req.headers['access-control-request-method']) ? req.headers['access-control-request-method'] : responseSettings.AccessControlAllowMethods);      if ('OPTIONS' == req.method) {         res.send(200);     }     else {         next();     }   }); 
like image 123
igorzg Avatar answered Sep 20 '22 04:09

igorzg