Xác thực AngularJS $ http, CORS và http


87

Bởi vì việc sử dụng xác thực CORS và http với AngularJS có thể khó khăn nên tôi đã chỉnh sửa câu hỏi để chia sẻ một bài học kinh nghiệm. Đầu tiên tôi muốn cảm ơn igorzg. Câu trả lời của anh ấy đã giúp tôi rất nhiều. Tình huống như sau: Bạn muốn gửi yêu cầu POST đến một miền khác với dịch vụ AngularJS $ http. Có một số điều phức tạp cần lưu ý khi tải AngularJS và thiết lập máy chủ.

Đầu tiên: Trong cấu hình ứng dụng của bạn, bạn phải cho phép cuộc gọi tên miền chéo

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

Thứ hai: Bạn phải chỉ định withCredentials: true và tên người dùng và mật khẩu vào yêu cầu.

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

Тthứ ba: Thiết lập máy chủ. Bạn phải cung cấp:

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

Đối với mọi yêu cầu. Khi bạn nhận được OPTION, bạn phải vượt qua:

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

Xác thực HTTP và mọi thứ khác sau đó.

Đây là ví dụ đầy đủ về cách sử dụng phía máy chủ với 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();
}
?>

Có một bài viết trên blog của tôi về vấn đề này có thể được xem ở đây .


Câu hỏi được chỉnh sửa.
Georgi Naumov

2
Tôi hơi bối rối, nó là anglejs nhưng bạn đã gói nó trong các thẻ PHP .... tôi đã bỏ lỡ điều gì đó?
onaclov2000

Đây chỉ là một ví dụ về logic phía máy chủ. Văn bản bên dưới "hird: Server setup" là logic phía máy chủ.
Georgi Naumov

@ onaclov2000 AngularJS dành cho phía khách hàng. Điều này có thể nói chuyện với bất kỳ phía máy chủ, PHP, Ruby, Perl, Python, Java, JavaScript ... Tôi có thể tiếp tục ..
Eric Hodonsky

1
Đây có phải là một câu hỏi? Nó là giống như một câu trả lời tốt :)
Mohammad Kermani

Câu trả lời:


43

Không, bạn không phải đặt thông tin đăng nhập, Bạn phải đặt tiêu đề ở phía máy khách, ví dụ:

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

Và ở phía máy chủ, bạn phải đặt tiêu đề cho đây là ví dụ cho 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();
    }


});

với CORS nói chung, máy chủ có phải cho phép tất cả các tiêu đề (Nội dung, Độ dài Nội dung, Người giới thiệu, v.v.) có trong yêu cầu thực, tức là không TÙY CHỌN không?
Kevin Meredith

@KevinMeredith Không, bạn không cần phải cho phép tất cả các tiêu đề, bạn chỉ có thể cho phép những gì bạn cần và thậm chí bạn có thể giới hạn ở một miền.
igorzg

1
làm thế nào để tôi biết những gì tôi cần?
Kevin Meredith

Cảm ơn vì câu trả lời hay của bạn :)
Kamruzzaman

1
Tôi bối rối, tại sao tôi không cần xác thực với điểm cuối nếu nó được bảo mật bằng xác thực cơ bản http?
Maxim Zubarev

3

Để thực hiện yêu cầu CORS, người ta phải thêm tiêu đề vào yêu cầu cùng với tiêu đề mà anh ta cần kiểm tra xem mode_header có được bật trong Apache hay không.

Để bật tiêu đề trong Ubuntu:

sudo a2enmod headers

Để máy chủ php chấp nhận yêu cầu từ việc sử dụng nguồn gốc khác nhau:

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"
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.