繁体   English   中英

在 laravel 中为特定路由禁用 csrf

[英]disable csrf in laravel for specific route

我有一个支付系统,数据被提交到第 3 方网站,然后被拖回......

当数据返回时,它会访问特定的 url,可以说 /ok 路由。 $_REQUEST['transaction']

但是由于 Laravel 中间件,我的令牌不匹配。 3rd 方支付 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 验证之外。 为了实现这一点,您需要将路由添加到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/*',
  ];
}

有关更多信息,请参阅文档

从 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]);

@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属性,并为“支付”添加一个中间条目。 它可以与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文件中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM