Laravel 5.5 手动验证 CSRF 令牌



我正在构建一个 API 驱动的 Laravel 5.5 应用程序。我还想使用可公开访问的 API 来处理 UI 驱动的请求。

我的问题是,在我的 api 身份验证中间件中,检测 UI 驱动的请求(ajax 请求(并允许它通过而无需尝试验证 api 身份验证凭据的最佳方法是什么?(也许尝试验证CSRF令牌?

您可以使用中间件添加对CSRF令牌的额外检查,尽管Laravel默认在Web路由(Doc(上这样做。

例如,添加此中间件以防止从 ajax 以外的任何内容进行访问:运行以下命令:

php artisan make:middleware AllowOnlyAjaxRequests

然后在中间件文件中:

    namespace AppHttpMiddleware;
    use Closure;
    class AllowOnlyAjaxRequests
    {
        /**
        * Handle an incoming request.
        *
        * @param  IlluminateHttpRequest  $request
        * @param  Closure  $next
        * @return mixed
        */
        public function handle($request, Closure $next)
        {
            if(!$request->ajax()) {
                // Handle the non-ajax request
                return response('', 405);
            }
            return $next($request);
        }
    }    

,然后在 app/Http/Kernel.php 中将'ajax' => AppHttpMiddlewareAllowOnlyAjaxRequests::class,添加到routeMiddleware数组

(中间件文档(

要检测通过 AJAX 发送的请求,您可以使用$request->ajax()代码。如果你想从验证CSRF中排除一些URI(谨慎地这样做(,你可以这样做。

在控制器中使用以下代码:

function isValidCsrf(): bool
{
    return (Session::token() == request()->header('X-CSRF-TOKEN')) ||
           (Session::token() == request()->post('_token'));
}

然后,您可以在控制器中使用此代码块:

if(request()->isMethod('POST') && isValidCsrf())
     /* Do something */
elseif(request()->isMethod('GET'))
     return view('....');
else
     abort(405,'only "GET, POST" methods are allowed");

在您看来,您可以在 ajax 请求中使用它:

$.ajax({
   url: 'your url',
   type: 'POST',
   ...
   headers: {
      'X-CSRF-TOKEN': $('meta[name="csrf-token"]').attr('content') // for separate js files or scripts from your php code
      'X-CSRF-TOKEN': "{{ csrf_token() }}" //for inline blade files
   },/*☝️ OR 👇*/
   data: {
      '_token': $('meta[name="csrf-token"]').attr('content') //for separate js files or scripts from your php code
      '_token': "{{ csrf_token() }}" //for inline blade files
   }
   ...
});

您可以在中间件中排除检查 CSRF 令牌VerifyCsrfToken特定路由。

在控制器中验证请求时排除它后,如果 CSRF 令牌返回false,则可以验证 CSRF 令牌$request->ajax()

您可以使用Session::token()csrf_token()函数验证 CSRF 令牌。

最新更新