AngularJS $ http, CORS ve http kimlik doğrulaması


87

AngularJS ile CORS ve http kimlik doğrulamasını kullanmak zor olabileceğinden, öğrenilen bir dersi paylaşmak için soruyu düzenledim. Önce igorzg'e teşekkür etmek istiyorum. Cevabı bana çok yardımcı oldu. Senaryo şu şekildedir: POST isteğini AngularJS $ http hizmeti ile farklı bir etki alanına göndermek istiyorsunuz. AngularJS ve sunucu kurulumunu alırken dikkat edilmesi gereken birkaç yanıltıcı şey vardır.

İlk olarak: Uygulama yapılandırmanızda, alanlar arası aramaya izin vermelisiniz

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

İkinci olarak: İstek için withCredentials: true ve kullanıcı adı ve şifreyi belirtmelisiniz.

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

Üçüncü: Sunucu kurulumu. Sağlamalısın:

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

Her istek için. SEÇENEK aldığınızda şunları geçmelisiniz:

/**
 *  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 kimlik doğrulaması ve diğer her şey bundan sonra gelir.

İşte php ile sunucu tarafının kullanımına tam bir örnek.

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

Blogumda bu konuyla ilgili burada görülebilen bir makale var .


Soru düzenlenmiştir.
Georgi Naumov

2
Biraz kafam karıştı, bu angularjs ama PHP etiketlerine sarılmışsınız .... Bir şey mi kaçırdım?
onaclov2000

Bu sadece sunucu tarafı mantığına bir örnektir. "Üçüncüsü: Sunucu kurulumu" altındaki metin, sunucu tarafı mantığıdır.
Georgi Naumov

@ onaclov2000 AngularJS müşteri tarafı içindir. Bu herhangi bir sunucu tarafı, PHP, Ruby, Perl, Python, Java, JavaScript ile konuşabilir ... Devam edebilirim ..
Eric Hodonsky

1
Bu bir soru mu? Daha çok iyi bir cevap gibi :)
Mohammad Kermani

Yanıtlar:


43

Hayır, kimlik bilgileri koymanıza gerek yok, istemci tarafına başlıklar koymanız gerekiyor, örneğin:

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

Ve sunucu tarafında, buna başlık koymanız gerekir nodejs için bir örnek:

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


});

Genel olarak CORS ile, sunucunun gerçek olarak mevcut olan tüm başlıklara (İçerik, İçerik-Uzunluk, Başvuran, vb.), yani SEÇENEKLER olmayan isteklere izin vermesi gerekiyor mu?
Kevin Meredith

@KevinMeredith Hayır, tüm başlıklara izin vermek zorunda değilsiniz, sadece ihtiyacınız olana izin verebilir ve hatta bir alan adıyla da sınırlayabilirsiniz.
igorzg

1
neye ihtiyacım olduğunu nasıl bilebilirim?
Kevin Meredith

Güzel cevabınız için teşekkürler :)
Kamruzzaman

1
Kafam karıştı, eğer uç nokta bir http temel kimlik doğrulaması ile güvence altına alınmışsa neden kimlik doğrulamasına ihtiyacım yok?
Maxim Zubarev

3

Bir CORS talebinde bulunmak için, Apache'de mode_header'ın etkin olup olmadığını kontrol etmek için ihtiyaç duyduğu şeyle birlikte isteğe başlıklar eklenmelidir.

Ubuntu'da başlıkları etkinleştirmek için:

sudo a2enmod headers

Php sunucusunun farklı kaynak kullanımından gelen isteği kabul etmesi için:

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"
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.