在 laravel 中禁用特定路由的 csrf
disable csrf in laravel for specific route
我有一个支付系统,其中数据被提交到第 3 方站点然后被拖回...
当数据 returns 它命中特定 url 让我们说 /ok 路由。 $_REQUEST['transaction']
.
但是由于 laravel 中间件,我得到了令牌不匹配。第 3 方支付 API 无法生成令牌,那么我该如何禁用它呢?仅适用于这条路线?
或者有更好的选择吗?
Route::get('/payment/ok', 'TransactionsController@Ok');
Route::get('/payment/fail', 'TransactionsController@Fail');
public function Ok( Request $request )
{
$transId = $request->get('trans_id');
if ( isset( $transId ) )
{
return $transId;
}
}
自版本 5.1 Laravel 的 VerifyCsrfToken 中间件允许指定路由,这些路由被排除在 CSRF 验证之外。为了实现这一点,您需要将路由添加到 $except 数组中 App\Http\Middleware\VerifyCsrfToken.php class:
<?php namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
class VerifyCsrfToken extends BaseVerifier
{
protected $except = [
'payment/*',
];
}
有关详细信息,请参阅 docs。
@jedrzej.kurylo 描述的技术适用于排除一两页。
如果您需要从 CSRF 验证中排除大量页面,则可以使用一种不同的技术,以适应未来的需要。
您可以对路由进行分段,并为每个路由应用不同的中间件。因此,您可以将您的支付路线放入单独的路线组中,而不对其应用 VerifyCsrfToken。方法如下。
1。创建路由文件
您会注意到在您的 routes
目录中,您有以下树:
routes/
routes/api.php
routes/web.php
在此处创建一个新文件,routes/payment.php
,并将上面的路由添加到其中:
<?php
use Illuminate\Support\Facades\Route;
Route::get('/payment/ok', 'TransactionsController@Ok');
Route::get('/payment/fail', 'TransactionsController@Fail');
2。使用 RouteServiceProvider
处理路由
在Laravel中,路由由app\Providers\RouteServiceProvider.php
处理。您会注意到这些函数:map()
和 mapWebRoutes()
。相应地添加到此文件(为简洁起见,我排除了股票评论)。
public function map()
{
$this->mapApiRoutes();
$this->mapWebRoutes();
$this->mapPaymentRoutes(); // <---- add this line
}
protected function mapWebRoutes()
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
protected function mapPaymentRoutes() // <--- Add this method
{
Route::middleware('payment') // <--- this line is important
->namespace($this->namespace)
->group(base_path('routes/payment.php'));
}
注意我们添加了一个新的中间件层。这对下一步很重要。
3。添加新的中间件层
路由组的中间件在 App\Http\Kernel.php
中定义。
更新 $middlewareGroups
属性,并为 'payment' 添加一个中间条目。它可以与 web
完全相同,但是 没有 VerifyCsrfToken
行。
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\NoClickjack::class,
\App\Http\Middleware\SecureReferrerPolicy::class,
\App\Http\Middleware\NoXssScripting::class,
],
// ********** Add this *******************
'payment' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
// This is the line you want to comment-out / remove
// \App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\NoClickjack::class,
\App\Http\Middleware\SecureReferrerPolicy::class,
\App\Http\Middleware\NoXssScripting::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
现在,每当您添加需要从 CSRF 令牌检查中排除的新路由时,将它们添加到 routes/payment.php
文件中。
因为 Laravel 7.7 您可以使用方法 withoutMiddleware
例如:
Route::get('/payment/ok', 'TransactionsController@Ok')
->withoutMiddleware([\App\Http\Middleware\VerifyCsrfToken::class]);
Route::get('/payment/fail', 'TransactionsController@Fail')
->withoutMiddleware([\App\Http\Middleware\VerifyCsrfToken::class]);
我有一个支付系统,其中数据被提交到第 3 方站点然后被拖回...
当数据 returns 它命中特定 url 让我们说 /ok 路由。 $_REQUEST['transaction']
.
但是由于 laravel 中间件,我得到了令牌不匹配。第 3 方支付 API 无法生成令牌,那么我该如何禁用它呢?仅适用于这条路线?
或者有更好的选择吗?
Route::get('/payment/ok', 'TransactionsController@Ok');
Route::get('/payment/fail', 'TransactionsController@Fail');
public function Ok( Request $request )
{
$transId = $request->get('trans_id');
if ( isset( $transId ) )
{
return $transId;
}
}
自版本 5.1 Laravel 的 VerifyCsrfToken 中间件允许指定路由,这些路由被排除在 CSRF 验证之外。为了实现这一点,您需要将路由添加到 $except 数组中 App\Http\Middleware\VerifyCsrfToken.php class:
<?php namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
class VerifyCsrfToken extends BaseVerifier
{
protected $except = [
'payment/*',
];
}
有关详细信息,请参阅 docs。
@jedrzej.kurylo 描述的技术适用于排除一两页。
如果您需要从 CSRF 验证中排除大量页面,则可以使用一种不同的技术,以适应未来的需要。
您可以对路由进行分段,并为每个路由应用不同的中间件。因此,您可以将您的支付路线放入单独的路线组中,而不对其应用 VerifyCsrfToken。方法如下。
1。创建路由文件
您会注意到在您的 routes
目录中,您有以下树:
routes/
routes/api.php
routes/web.php
在此处创建一个新文件,routes/payment.php
,并将上面的路由添加到其中:
<?php
use Illuminate\Support\Facades\Route;
Route::get('/payment/ok', 'TransactionsController@Ok');
Route::get('/payment/fail', 'TransactionsController@Fail');
2。使用 RouteServiceProvider
处理路由在Laravel中,路由由app\Providers\RouteServiceProvider.php
处理。您会注意到这些函数:map()
和 mapWebRoutes()
。相应地添加到此文件(为简洁起见,我排除了股票评论)。
public function map()
{
$this->mapApiRoutes();
$this->mapWebRoutes();
$this->mapPaymentRoutes(); // <---- add this line
}
protected function mapWebRoutes()
{
Route::middleware('web')
->namespace($this->namespace)
->group(base_path('routes/web.php'));
}
protected function mapPaymentRoutes() // <--- Add this method
{
Route::middleware('payment') // <--- this line is important
->namespace($this->namespace)
->group(base_path('routes/payment.php'));
}
注意我们添加了一个新的中间件层。这对下一步很重要。
3。添加新的中间件层
路由组的中间件在 App\Http\Kernel.php
中定义。
更新 $middlewareGroups
属性,并为 'payment' 添加一个中间条目。它可以与 web
完全相同,但是 没有 VerifyCsrfToken
行。
protected $middlewareGroups = [
'web' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\NoClickjack::class,
\App\Http\Middleware\SecureReferrerPolicy::class,
\App\Http\Middleware\NoXssScripting::class,
],
// ********** Add this *******************
'payment' => [
\App\Http\Middleware\EncryptCookies::class,
\Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
\Illuminate\Session\Middleware\StartSession::class,
\Illuminate\Session\Middleware\AuthenticateSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class,
// This is the line you want to comment-out / remove
// \App\Http\Middleware\VerifyCsrfToken::class,
\Illuminate\Routing\Middleware\SubstituteBindings::class,
\App\Http\Middleware\NoClickjack::class,
\App\Http\Middleware\SecureReferrerPolicy::class,
\App\Http\Middleware\NoXssScripting::class,
],
'api' => [
'throttle:60,1',
'bindings',
],
];
现在,每当您添加需要从 CSRF 令牌检查中排除的新路由时,将它们添加到 routes/payment.php
文件中。
因为 Laravel 7.7 您可以使用方法 withoutMiddleware
例如:
Route::get('/payment/ok', 'TransactionsController@Ok')
->withoutMiddleware([\App\Http\Middleware\VerifyCsrfToken::class]);
Route::get('/payment/fail', 'TransactionsController@Fail')
->withoutMiddleware([\App\Http\Middleware\VerifyCsrfToken::class]);