Laravel 419 page expired при оплате через free kassa

Я встроил виджет free kassa на сайт. Когда происходит оплата, их сервер отправляет POST запрос на /payment/result. В логах free kassa написано, что была ошибка 419 page expired. Это из-за того ,что не передается csrf токен. Значит нужно добавить этот url в исключение.

web.php

// web.php

// Роут, на который free kassa шлёт запрос
Route::post('/payment/result', function (Request $request){
    \Illuminate\Support\Facades\Log::info($request->all());
    return 123;
})->middleware(\App\Http\Middleware\FreeKassaVerifyCsrfToken::class);


Route::any('/{any}', function () {
    return view('index');
})->where('any', '.*');

VerifyCsrfToken.php

<?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 = [
        '/payment/result',
    ];
}

Я создал middleware FreeKassaVerifyCsrfToken для обработки роутов free kassa, но при оплате по запросу /payment/result ошибка 419 page expired.

use Illuminate\ Foundation\ Http\ Middleware\ VerifyCsrfToken as Middleware;

class FreeKassaVerifyCsrfToken extends Middleware {

  private $whiteList = [
    '136.243.38.147',
    '136.243.38.149',
    '136.243.38.150',
    '136.243.38.151',
    '136.243.38.189',
    '136.243.38.108',
    '136.243.38.*',
  ];

  /**
   * Handle an incoming request.
   *
   * @param \Illuminate\Http\Request $request
   * @param \Closure $next
   * @return mixed
   */
  public
  function handle(Request $request, Closure $next) {
    Log::info('123');
    if (!in_array($request - > ip(), $this - > whiteList)) {
      abort(403);
    }
    return $next($request);
  }
}

В лог файл тоже ничего не выводится, то есть handler даже не срабатывает. Но, если в web.php прицепить middleware FreeKassaVerifyCsrfToken к роуту /{any}, то при любых запросах - 403 ошибка, и в лог выводится 123 В чём моя ошибка?


Ответы (1 шт):

Автор решения: Walfter

Мидлварь VerifyCsrfToken исключает маршруты которые есть в внутри вашего приложения, метод except принимает значения урлов из роутинга с мидлварной группой web

Теперь о ваших черепахах. У вас есть пост запрос такого типа

// web.php
Route::post('/payment/result', function(Request $request) {\
    Illuminate\ Support\ Facades\ Log::info($request - > all());
  });
});

Вешаем его в исключения CSRF защиты

<?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 = [
        '/payment/result',
    ];
}

Делаем свою мидлварь для обработки уролов фри кассы с хандлером типа

/**
 * Handle an incoming request.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Closure  $next
 *
 * @return mixed
 */
public function handle(Request $request, Closure $next)
{
    if (!in_array($request->ip(), $this->whiteList)) {
        abort(403);
    }
    return $next($request);
}

P.S.: Пропа whiteList содержит массив разрешённых апишников для доступа к этому маршруту

Теперь далее: регистрируем созданную мидлварь для роута

// web.php
Route::post('/payment/result', function(Request $request) {
    Illuminate\ Support\ Facades\ Log::info($request - > all());
  });
})->middleware(YourMiddleware::class);

Если вкратце то как то так.

UPDATE:

Мидлварь VerifyCsrfToken цепляется через kernel который лежит в папке http на группу web по этому его не надо вручную добавлять к роутам, все роутый из файла web.php уже имеют эту группу на уровне роут провайдера

→ Ссылка