AngularJS $ http-, CORS- und http-Authentifizierung

88

Da die Verwendung der CORS- und http-Authentifizierung mit AngularJS schwierig sein kann, habe ich die Frage bearbeitet, um eine gelernte Lektion zu teilen. Zuerst möchte ich mich bei igorzg bedanken. Seine Antwort hat mir sehr geholfen. Das Szenario ist das folgende: Sie möchten eine POST-Anforderung mit dem AngularJS $ http-Dienst an eine andere Domäne senden. Es gibt einige knifflige Dinge zu beachten, wenn Sie AngularJS und das Server-Setup erhalten.

Erstens: In Ihrer Anwendungskonfiguration müssen Sie domänenübergreifende Anrufe zulassen

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

Zweitens: Sie müssen withCredentials: true und Benutzername und Passwort in der Anfrage angeben.

 /**
  *  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. Du musst bereitstellen:

/**
 *  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");

Für jede Anfrage. Wenn Sie OPTION erhalten, müssen Sie Folgendes bestehen:

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

Die HTTP-Authentifizierung und alles andere kommt danach.

Hier ist ein vollständiges Beispiel für die Verwendung der Serverseite mit 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();
}
?>

In meinem Blog gibt es einen Artikel zu diesem Thema, der hier zu sehen ist .

Georgi Naumov
quelle
Die Frage wird bearbeitet.
Georgi Naumov
2
Ich bin ein wenig verwirrt, es ist eckig, aber Sie haben es in PHP-Tags verpackt ... habe ich etwas verpasst?
Onaclov2000
Dies ist nur ein Beispiel für serverseitige Logik. Der Text unter ":hird: Server-Setup" ist serverseitige Logik.
Georgi Naumov
@ onaclov2000 AngularJS ist für die Client-Seite. Dies kann mit jeder Serverseite sprechen, PHP, Ruby, Perl, Python, Java, JavaScript ... Ich könnte weitermachen ...
Eric Hodonsky
1
Ist das eine Frage? Es ist eher eine gute Antwort :)
Mohammad Kermani

Antworten:

43

Nein, Sie müssen keine Anmeldeinformationen eingeben. Sie müssen Header auf der Clientseite einfügen, z.

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

Und auf der Serverseite müssen Sie Header einfügen. Dies ist ein Beispiel für 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();
    }


});
igorzg
quelle
Muss der Server bei CORS im Allgemeinen alle Header (Inhalt, Inhaltslänge, Referer usw.) zulassen, die in der realen Anforderung, dh Nicht-OPTIONEN, vorhanden sind?
Kevin Meredith
@ KevinMeredith Nein, Sie müssen nicht alle Header zulassen, Sie können nur das zulassen, was Sie benötigen, und Sie können sogar auf eine Domain beschränken.
Igorzg
1
Woher weiß ich, was ich brauche?
Kevin Meredith
Vielen Dank für Ihre nette Antwort :)
Kamruzzaman
1
Ich bin verwirrt, warum muss ich mich nicht beim Endpunkt authentifizieren, wenn dieser durch eine http-Basisauthentifizierung gesichert ist.
Maxim Zubarev
3

Um eine CORS-Anfrage zu stellen, muss der Anfrage Header hinzugefügt werden, zusammen mit dem gleichen, den er benötigt, um zu überprüfen, ob mode_header in Apache aktiviert ist.

So aktivieren Sie Header in Ubuntu:

sudo a2enmod headers

Damit der PHP-Server Anfragen unterschiedlicher Herkunft akzeptiert, verwenden Sie:

Header set Access-Control-Allow-Origin *
Header set Access-Control-Allow-Methods "GET, POST, PUT, DELETE"
Header always set Access-Control-Allow-Headers "x-requested-with, Content-Type, origin, authorization, accept, client-security-token"
Vijay Kumar
quelle