CSRF 保護(hù)
CSRF 保護(hù)
CSRF 介紹
介紹
Laravel 可以輕松使地保護(hù)你的應(yīng)用程序免受 cross-site request forgery (CSRF) 攻擊,跨站點(diǎn)請(qǐng)求偽造是一種惡意攻擊,它憑借已通過(guò)身份驗(yàn)證的用戶(hù)身份來(lái)運(yùn)行未經(jīng)過(guò)授權(quán)的命令。
Laravel 會(huì)自動(dòng)為每個(gè)活躍的用戶(hù)的會(huì)話(huà)生成一個(gè) CSRF「令牌」。該令牌用于驗(yàn)證經(jīng)過(guò)身份驗(yàn)證的用戶(hù)是否是向應(yīng)用程序發(fā)出請(qǐng)求的用戶(hù)。
無(wú)論何時(shí),當(dāng)您在應(yīng)用程序中定義 HTML 表單時(shí),都應(yīng)該在表單中包含一個(gè)隱藏的 CSRF 標(biāo)記字段,以便 CSRF 保護(hù)中間件可以驗(yàn)證該請(qǐng)求,你可以使用 @csrf
Blade 指令來(lái)生成令牌字段,如下:
<form method="POST" action="/profile"> @csrf ... </form>
包含在 web 中間件組里 VerifyCsrfToken
中間件 會(huì)自動(dòng)驗(yàn)證請(qǐng)求里的令牌是否與存儲(chǔ)在會(huì)話(huà)中令牌匹配。
CSRF 令牌 & JavaScript
當(dāng)構(gòu)建由 JavaScript 驅(qū)動(dòng)的應(yīng)用時(shí),可以方便的讓 JavaScript HTTP
函數(shù)庫(kù)發(fā)起每一個(gè)請(qǐng)求時(shí)自動(dòng)附上 CSRF 令牌。默認(rèn)情況下,resources/js/bootstrap.js
文件會(huì)用 Axios HTTP 函數(shù)庫(kù)注冊(cè)的 csrf-token
meta 標(biāo)簽中的值。如果你不使用這個(gè)函數(shù)庫(kù),你需要手動(dòng)為你的應(yīng)用配置此行為。
CSRF 白名單
有時(shí)候你可能希望設(shè)置一組不需要的 CSRF 保護(hù)的 URL 。例如,如果你正在使用 Stripe 處理付款并使用了他們的 webhook 系統(tǒng),你會(huì)需要從 CSRF 的保護(hù)中排除 Stripe webhook 處理程序路由,因?yàn)?Stripe 并不會(huì)給你的路由發(fā)送 CSRF 令牌。
典型做法,你可以把這類(lèi)路由放 routes/web.php
外,因?yàn)?RouteServiceProvider
的 web
中間件適用于該文件中的所有路由。不過(guò),你也可以通過(guò)將這類(lèi) URL 添加到 VerifyCsrfToken
中間件的 $except
屬性來(lái)排除對(duì)這類(lèi)路由的 CSRF 保護(hù),如下所示:
<?php namespace App\Http\Middleware; use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware; class VerifyCsrfToken extends Middleware{ /** * The URIs that should be excluded from CSRF verification. * * @var array */ protected $except = [ 'stripe/*', 'http://example.com/foo/bar', 'http://example.com/foo/*', ]; }
{tip} 當(dāng) 運(yùn)行測(cè)試 時(shí), CSRF 中間件會(huì)自動(dòng)禁用。
X-CSRF-TOKEN
除了檢查 POST 參數(shù)中的 CSRF 令牌外, VerifyCsrfToken
中間件還會(huì)檢查 X-CSRF-TOKEN
請(qǐng)求頭。你應(yīng)該將令牌保存在 HTML meta
標(biāo)簽中,如下:
<meta name="csrf-token" content="{{ csrf_token() }}">
然后,一旦你創(chuàng)建了 meta
標(biāo)簽,就可以指示像 jQuery 這樣的庫(kù)自動(dòng)將令牌添加到所有請(qǐng)求的頭信息中。還可以為基于 AJAX 的應(yīng)用提供簡(jiǎn)單,方便的 CSRF 保護(hù)。如下:
$.ajaxSetup({ headers: { 'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') } });
{tip} 默認(rèn)情況下,
resources/js/bootstrap.js
文件會(huì)用 Axios HTTP 函數(shù)庫(kù)注冊(cè)csrf-token
meta 標(biāo)簽中的值。如果不使用這個(gè)函數(shù)庫(kù),則需要為你的應(yīng)用手動(dòng)配置此行為。
X-XSRF-TOKEN
Laravel 將當(dāng)前的 CSRF 令牌存儲(chǔ)在一個(gè) XSRF-TOKEN
cookie
中,該 cookie 包含在框架生成的每個(gè)響應(yīng)中。你可以使用 cookie 值來(lái)設(shè)置 X-XSRF-TOKEN
請(qǐng)求頭。
這個(gè) cookie 主要是作為一種方便的方式發(fā)送的,因?yàn)橐恍? JavaScript 框架和庫(kù),例如 Angular 和 Axios ,會(huì)自動(dòng)將它的值放入 X-XSRF-TOKEN
頭中。