簡介
跨站請求偽造是一種通過偽裝授權用戶的請求來利用授信網站的惡意漏洞。Laravel 使得防止應用遭到跨站請求偽造攻擊變得簡單。
Laravel 自動為每一個被應用管理的有效用戶會話生成一個 CSRF “令牌”,該令牌用於驗證授權用戶和發起請求者是否是同一個人。
任何時候在 Laravel 應用中定義HTML表單,都需要在表單中引入CSRF令牌字段,這樣CSRF保護中間件才能夠正常驗證請求。想要生成包含 CSRF 令牌的隱藏輸入字段,可以使用輔助函數 csrf_field 來實現:
<form method="POST" action="/profile">
{{ csrf_field() }}
...
</form>
中間件組 web 中的中間件VerifyCsrfToken 會自動為我們驗證請求輸入的 token 值和 Session 中存儲的 token 是否一致。
從 CSRF 保護中排除指定 URL
有時候我們需要從 CSRF 保護中排除一些 URL,例如,如果你使用了 Stripe 來處理支付並用到他們的 webhook 系統,這時候就需要從 Laravel 的 CSRF 保護中排除 webhook 處理器路由,因為Stripe並不知道要傳什么token值給我們定義的路由。
通常我們需要將這種類型的路由放到文件 routes/web.php 里,中間件組 web 之外。此外,你也可以在 VerifyCsrfToken 中間件中將要排除的 URL 添加到 $except 屬性數組:
<?php
namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
class VerifyCsrfToken extends BaseVerifier
{
/**
*從CSRF驗證中排除的URL
*
* @var array
*/
protected $except = [
'stripe/*',
];
}
X-CSRF-Token
除了將 CSRF 令牌作為 POST 參數進行驗證外,還可以通過設置 X-CSRF-Token 請求頭來實現驗證,VerifyCsrfToken 中間件會檢查 X-CSRF-TOKEN 請求頭,首先創建一個 meta 標簽並將令牌保存到該 meta 標簽:
<meta name="csrf-token" content="{{ csrf_token() }}">
然后在 js 庫(如 jQuery)中添加該令牌到所有請求頭,這為基於 AJAX 的應用提供了簡單、方便的方式來避免 CSRF 攻擊:
$.ajaxSetup({
headers: {
'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content')
}
});
X-XSRF-Token
Laravel 還會將 CSRF 令牌保存到名為 XSRF-TOKEN 的 Cookie 中,你可以使用該 Cookie 值來設置 X-XSRF-TOKEN請求頭。一些 JavaScript 框架,比如 Angular,會為你自動進行設置,基本上你不太需要手動設置這個值。
