AngularJS $http, CORS and http authentication

angularjs, cors

Solution

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();
    }


});

Problem

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 * gonaumov@gmail.com 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 * gonaumov@gmail.com 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 * gonaumov@gmail.com 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 * gonaumov@gmail.com 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 * gonaumov@gmail.com 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.

Original source