簡體   English   中英

如何在 PHP (Laravel) 中驗證請求的源域

[英]How to verify the origin domain of a request in PHP (Laravel)

我正在開發一個 Laravel 應用程序,我正在為其他網站構建一些 API。 但我試圖讓我的 API 的實現盡可能簡單。 我的期望是用戶只會在 HTML 頭中使用這個標簽:

<script src="api.mydomain.com">

Now I have a controller on this URL that provides the source javascript with the content-type header, but before it goes there, the router will first execute my authentication middleware. 假設它看起來像這樣:

public static $users = [
    'client1.com',
    'client2.com',
    'client3.com'
];

public function handle(Request $request, Closure $next)
{
    $origin = "HERE I NEED THE ORIGIN URL"; // e.g. client4.com

    if ( !in_array($origin, self::$users) ) {

        abort(401);

    }

    return $next($request);
}

從代碼中可以看出,我需要檢索$origin變量。 因此,如果網站client1.com將嘗試插入我的javascript ,它將成功獲得 javascript 代碼。 如果client4.com嘗試訪問它,則會收到 401 錯誤。

我發現了$_SERVER['HTTP_REFERER']或 Laravel 的$request->server('HTTP_REFERER') 的方法,但是這些數據可能是偽造的,對吧?

在最好的情況下,我想檢索原始域,當不可用時(例如,來自私有 cURL 請求),我想獲取 IP 地址。 當然,我需要它是安全的——clients1/2/3 為我的 API 付費,其他人沒有。

我該怎么做? 或者有沒有更好的原產地認證方法?

所有引用的東西都可以被欺騙。

付費 API 的最佳方式是發出 API 呼叫密鑰。

您的 API 可以顯示結果或錯誤,具體取決於客戶端是否具有正確的 API 密鑰並已付費。

您還應該保留帶有時間戳和 clientID 以及 IP 地址的 API 調用的日志表。 因此,您可以不時從通話頻率和 IP 模式中檢查您的付費客戶是否與其他人共享他的密鑰。

不時清理此日志表以保持其小而高效。

所以我通過在中間件處理程序中添加標題(感謝@jewishmoses 的靈感)來解決這個問題。 我的 Javascript 基本上對每個人都可用,但它只提供一個按鈕,試圖創建一個內部包含 iframe 的新元素(我的應用程序也可用作 API)。

假設我在服務器上有一個關聯數組,我可以從任何數據庫動態填充:

$clients = [
    'client1' => 'paying-customer.com',
    'client2' => 'also-paying-customer.com',
];

...我的 API 路線定義為“ api.mydomain.com/{client} ”和“ api.mydomain.com/{client}/iframe 該處理程序負責添加標頭:

public function handle(Request $request, Closure $next)
{
    $client = $request->route('client',null);

    $clientSet = $client !== null;
    $clientAccepted = isset($clients[$client]);

    if ( $clientSet and !$clientAccepted ) {

        abort(401);

    }

    $response = $next($request);


    if( $clientSet and isset($response->headers) and $response->headers instanceof ResponseHeaderBag){

        $clientDomain = $clients[$client];

        $response->headers->add([
            'Content-Security-Policy' => "frame-ancestors https://*.$clientDomain/ https://$clientDomain/"
        ]);
    }



    return $response;
}

現在可能會發生什么:

  1. client1 成功從api.mydomain.com/client1導入 javascript ,它將嘗試訪問api.mydomain.com/client1/iframe (也成功)
  2. client3 嘗試從api.mydomain.com/client3導入 javascript 失敗
  3. client3 成功從api.mydomain.com/client1導入 javascript ,它將嘗試訪問api.mydomain.com/client1/iframe (被 headers 拒絕)

也許有一種更優雅的方法來阻止加載 javascript,但是在我看來,提供我自己的應用程序作為 API(在 iframe 中)是足夠安全的,因為我可以控制誰可以使用它,現代瀏覽器將幫助我阻止“小偷” ”。 資源對解決我的問題最有幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM