我有一个支付系统,数据提交给第三方网站,然后拖回来......
当数据返回时,它会命中特定的url让我们说/ ok route。 $_REQUEST['transaction']
。
但由于laravel中间件我得到令牌不匹配。第三方支付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;
}
}
答案 0 :(得分:65)
由于版本 5.1 ,Laravel的 VerifyCsrfToken 中间件允许指定从CSRF验证中排除的路由。为了实现这一目标,您需要在 App \ Http \ Middleware \ VerifyCsrfToken.php 类中将路径添加到 $ except 数组:
<?php namespace App\Http\Middleware;
use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
class VerifyCsrfToken extends BaseVerifier
{
protected $except = [
'payment/*',
];
}
有关详细信息,请参阅docs。
答案 1 :(得分:3)
@ jedrzej.kurylo描述的技术非常适合排除一两个页面。
如果您需要从CSRF验证中排除很多页面,并且具有更多的面向未来的能力,那么这是另一种技术。
您可以细分路线,并为每个路线应用不同的中间件。因此,您可以将付款路线放入单独的路线组中,而不对它们应用VerifyCsrfToken。就是这样。
您会发现在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');
在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'));
}
注意,我们添加了一个新的中间件层。这对于下一步很重要。
您的路由组的中间件在App\Http\Kernel.php
中定义。
更新$middlewareGroups
属性,并为“付款”添加一个中间条目。它可以与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
文件中。
答案 2 :(得分:3)
从Laravel 7.7开始,您可以使用方法withoutMiddleware
,例如:
Route::get('/payment/ok', 'TransactionsController@Ok')->withoutMiddleware(['csrf']);
Route::get('/payment/fail', 'TransactionsController@Fail')->withoutMiddleware(['csrf']);