Laravel 5.5 手动验证 CSRF 令牌

问题描述 投票:0回答:3

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

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

php laravel laravel-5
3个回答
2
投票

您可以使用中间件来添加对 CSRF 令牌的额外检查,尽管 Laravel 默认情况下会在 Web 路由上执行此操作(Doc)。

例如添加此中间件以防止除ajax之外的任何内容进行访问: 运行这个命令:

php artisan make:middleware AllowOnlyAjaxRequests

然后在中间件文件中:

    namespace App\Http\Middleware;

    use Closure;

    class AllowOnlyAjaxRequests
    {
        /**
        * Handle an incoming request.
        *
        * @param  \Illuminate\Http\Request  $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);
        }
    }    

然后将

'ajax' => \App\Http\Middleware\AllowOnlyAjaxRequests::class,
添加到
routeMiddleware
 中的 
app/Http/Kernel.php

数组中

(中间件文档)

为了检测通过ajax发送的请求,您可以使用

$request->ajax()
代码。 如果您想从验证 CSRF 中排除某些 URI(请谨慎操作),您可以这样做this


0
投票

在控制器中使用此代码:

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
   }
   ...
});

0
投票

您可以在

VerifyCsrfToken
中间件中从检查 CSRF 令牌中排除特定路由。

在控制器中验证请求时将其排除后,如果

$request->ajax()
返回
false
,则可以验证 CSRF 令牌。

您可以使用

Session::token()
csrf_token()
函数验证 CSRF 令牌。

© www.soinside.com 2019 - 2024. All rights reserved.