javascript 做 cors request 並夾帶 authorization (帳號密碼) 資料給 php

關鍵點在於不論是 XMLHttpRequest 或者是用 ajax,只要有夾帶 authroization (user name & password) 要做認證的話,會多一個 OPTIONS request,而且 javascript 這邊也要做修改。

注意: 這是很不安全的CORS,有可能被釣魚,所以盡可能不要使用

一般狀況下透過 XMLHttpRequest 或 ajax 去呼叫其他 server 上的 api 或網頁,只要對方 server 的 cors 設定有做好就沒問題,但是如果要加上 authorization 資訊,javascript 這邊要指定這個 request 必須是 with credentials,且要把 authorization 資料放在 header 中。

<!DOCTYPE html>
<html>
    <head>
        <meta HTTP-EQUIV="CONTENT-TYPE" CONTENT="text/html; charset=utf-8">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.2.2/jquery.min.js"></script>
    </head>
    <body>
        <div class="container" style="padding-top:40px;">
<span id="i01">test</span>
<span id="i02">test2</span>
        </div>
    </body>
<script>
// jquery
$('#i01').click(function(){
        $.ajax({
                type: "GET",
                url: "http://API.SERVER.URL/PATH/TO/API",
                dataType: 'json',
                async: false,
                beforeSend: function(request){
                    request.withCredentials = true;
                    request.setRequestHeader("Authorization" , "Basic AUTHORIZATION_DATA==");  // AUTHORIZATION_DATA = btoa("USERNAME:PASSWORD");
                },
                success: function (){
                        alert('Success!');
                }
        });
});

// javascript
$('#i02').click(function(){
  var xhttp = new XMLHttpRequest();
  xhttp.onreadystatechange = function() {
      if (this.readyState == 4 && this.status == 200) {
        alert('Success!');
      }
  };
  var url = 'ttp://API.SERVER.URL/PATH/TO/API';
  xhttp.open("GET", url, true);
  xhttp.setRequestHeader('Authorization','Basic AUTHORIZATION_DATA==');  // AUTHORIZATION_DATA = btoa("USERNAME:PASSWORD");
  xhttp.send();
});

</script>
</html>

而在被呼叫的 api 部分(以 php phalcon framework 為例子),則不僅要把 X-Requested-With 加入 allow headers 裏頭,連 Authorization 也要。

public function apiAction()
{
        $resp = new PhalconHttpResponse();
        $resp->setHeader("Access-Control-Allow-Origin", "*");
        $resp->setHeader('Access-Control-Allow-Headers', 'X-Requested-With, Authorization');
        $resp->sendHeaders();

        $this->view->disable();
        //$headers = apache_request_headers();
        //var_dump($headers['Authorization']);
        $resp->setHeader("Content-Type", "application/json");
        $resp->setStatusCode(200, "OK");
        $resp->setContent('{"message": "Not a valid verifiy"}');
        $resp->send();
        return;
}

最後就可以看到這樣的結果。

javascript cors with authorization