PHP 設定多域名允許跨域訪問
跨域是Web開發中常見的問題,解決跨域的方法也有很多。本文以CORS(跨域資源訪問)方式和大家一起來了解一下針對PHP語言,如何設定允許多域名訪問。
首先,我們還需要對一些基礎知識有了解。
(1)伺服器變數
針對PHP語言而言,伺服器變數儲存在$_SERVER陣列中,在這個陣列中有一個特殊的鍵值:HTTP_ORIGIN。這個鍵只在跨域的時候才會存在值,同源時為空字串。
(2)響應頭設定允許某域名訪問:access-control-allow-origin
通過PHP的header函式可以設定允許某域名跨域訪問,形式為header('access_control_allow_origin:*')。
OK,下面直接上程式碼
$allow_origin = array(
'a.baidu.com',
'b.baidu.com',
);
$origin = isset($_SERVER['HTTP_ORIGIN']) ? $_SERVER['HTTP_ORIGIN'] : ''; //跨域訪問的時候才會存在此欄位
if (in_array($origin, $allow_origin)) {
header('Access-Control-Allow-Origin:' . $origin);
} else {
return;
}
note:
有一點要特別注意:通過介面工具請求介面時$_SERVER['HTTP_ORIGIN']變數也為空字串,如果你的服務外網可以訪問,那你一定要注意了。
================20181107 更新===============
背景:
11月2號服務上線,上線之後發現郵件組裡收到了一些亂七八糟的郵件而且資料庫裡也插入了一些亂碼的資料。可以判定,後端服務被攻擊了。
追查:
檢視線上機器日誌,發現日誌中記錄的來源域名均為空,之前做的策略無效。後端Web Server是Nginx,在經過外網到內網流量排程、接入層轉發之後,業務中無法取到$_SERVER['HTTP_ORIGIN']變數。
解決:
針對這種情況,想了以後幾種解決方案:
(1)在Nginx中配置跨域
(2)做郵箱(手機號)驗證碼校驗
(3)前端做拖圖校驗
第一種方案實踐不可行,不知道是不是配置的問題,不起作用。
第三種方案需要使用到PHP的GD庫、redis快取以及開發量大,也棄用。
經過與PM FE UE商定,最終採用手機號進行驗證碼校驗。
經過兩天的開發、測試、上線,目前線上尚未發現之前的攻擊問題。
note:後端服務介面不可能完全避免被刷,可做的就是增加黑客的攻擊成本。