CSRF 令牌在带有 Ajax 请求的 Laravel 5.1 异常处理程序中不起作用

Posted

技术标签:

【中文标题】CSRF 令牌在带有 Ajax 请求的 Laravel 5.1 异常处理程序中不起作用【英文标题】:CSRF Token not working in Laravel 5.1 Exceptions Handler with an Ajax request 【发布时间】:2016-08-23 02:38:22 【问题描述】:

我有一个 Laravel 5.1 应用程序,在启动时加载了 Ajax 内容。

我已将 CSRF 元标记放置到页眉:

<meta name="csrf-token" content=" csrf_token() " />

我在 jquery ajax 请求中使用它:

$.ajaxSetup(

  headers:
  
    "X-CSRF-TOKEN": $('meta[name="csrf-token"]').attr("content")
  
);

在正常情况下一切正常。但是,当我在没有前一个会话的情况下打开 404 错误页面时,我的 ajax 请求会出错: VerifyCsrfToken.php 中的 TokenMismatchException

我在文件中有一个 404 错误处理程序:app\Exceptions\Handler.php

public function render($request, Exception $e)

  if ($e instanceof NotFoundHttpException)
  
    $foo = \App\Foo::foo();
    return \Response::make(view("errors.404", compact("foo")), 404);
  

  return parent::render($request, $e);

我可以通过打开一个私人浏览器窗口并打开我的站点以及一个不存在页面的 URL 来重复此错误。它在页面重新加载时仍然存在。但是,如果我转到现有页面并再次尝试 404 url​​,它就可以正常工作。

任何想法如何解决这个问题?

编辑:

我尝试检查多个 ajax 请求,似乎每个请求都有一个带有不同令牌的完全不同的会话:

$request->session()->token();

【问题讨论】:

【参考方案1】:

在你的 CSRF 中间件中在 return parent::handle($request, $next): 之前添加这个:

if($request->ajax())

    \Input::merge([
        '_token' => $request->header('X-CSRF-Token')
    ]);

编辑: csrf_token() 是否在该 404 页面上返回任何内容?我发现某事很有趣here。看起来和你的问题很相似

【讨论】:

不走运。 Middleware\VerifyCsrfToken.php 函数 tokensMatch 已经通过: $token = $request->input('_token') ?: $request->header('X-CSRF-TOKEN'); 是的,csrf_token() 正在返回一个值。我可以将用户重定向到一个单独的 404 url​​,从而避免这个问题。然后用户会丢失原始网址。我不得不这样做似乎很奇怪。

以上是关于CSRF 令牌在带有 Ajax 请求的 Laravel 5.1 异常处理程序中不起作用的主要内容,如果未能解决你的问题,请参考以下文章

通过 AJAX 获取 CSRF 令牌

如何在 Cakephp 3 的 ajax 调用中定义 CSRF 令牌。此外,对于某些 ajax 请求,如何关闭 CSRF

带有 django 的 JQuery AJAX 获取 csrf 错误 403

公开会话的 CSRF 保护令牌是不是安全?

如何在 ajax POST 请求中设置标头以包含 CSRF 令牌

laravel 5中多个异步ajax请求中的CSRF令牌不匹配错误?