【问题标题】:How to prevent the TokenMismatchException reliably during Ajax calls in Laravel?如何在 Laravel 的 Ajax 调用期间可靠地防止 TokenMismatchException?
【发布时间】:2017-08-11 14:53:56
【问题描述】:

我知道之前有很多关于在 Laravel 中处理 Ajax 调用中的 CSRF 令牌的问题。 Laravel 文档 specify a way 在任何 Ajax 请求中传递 csrf_token 值,如下所示:

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

并且这正是我在我的应用中所做的

但是,仍然有很多情况下TokenMismatchException 被抛出并登录到服务器。我认为其中一个原因如下:

  1. 用户加载页面并保持页面打开
  2. Laravel 会话过期
  3. 用户返回 PC 并触发 Ajax 调用(例如,通过单击按钮)
  4. Ajax 调用从元标记中收集 csrf-token

现在,通过调用传递的 csrf-token 值当然是错误的,因为 Laravel 会话不存在并且需要重新生成。

Laravel 文档还 suggests 使用 XSRF-TOKEN cookie。但是,该 cookie 显然具有与 laravel_session cookie 相同的到期日期,这对我也无济于事。

请注意,用户不一定要经过身份验证才能生成 Ajax 调用,它们可以由来宾用户触发,并且所有这些都将针对跨站点请求伪造进行检查。

在我上面描述的情况下,有没有办法解决这个问题并防止TokenMismatchException

旁注:

我描述的情况可能不是唯一的。在过去的 24 小时内,异常被抛出并记录了 36 次,我确信这些事件不能都与同一个问题相关联,尤其是因为这些是各种 Ajax 调用——GET 和 POST。

【问题讨论】:

    标签: php ajax laravel laravel-5.2


    【解决方案1】:

    尝试另一种使用 ajax 传递令牌的方式:

    $.ajax({
        type: 'POST',
        url: '/your/url',
    
        headers: {
            'X-CSRF-TOKEN': '{{ csrf_token() }}'
        },
    
        success: function (data) {
            //do something
        }
    });
    

    或者,您可以选择从 CSRF 保护中排除 URI:

    通常,您应该将这些类型的路由放在 RouteServiceProvider 应用于 routes/web.php 文件中的所有路由的 Web 中间件组之外。但是,您也可以通过将路由的 URI 添加到 VerifyCsrfToken 中间件的 $except 属性来排除路由:

    <?php
    
    namespace App\Http\Middleware;
    
    use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as BaseVerifier;
    
    class VerifyCsrfToken extends BaseVerifier
    {
        /**
         * The URIs that should be excluded from CSRF verification.
         *
         * @var array
         */
        protected $except = [
            'stripe/*',
        ];
    }
    

    Source/docs here

    【讨论】:

      【解决方案2】:

      在要添加 ajax 代码的页面中包含以下内容。

      <input type="hidden" id="token" name="_token" value="<?php echo csrf_token();?>" />
      
      var token = $('#token').val();
      $.ajax({
             url: "your-url",
             method: "POST",
             data: {
               _token : token,
               required_fields: your-fields
             },
             success: function(result) {
               if(result.success == true) {
                // required action upon success
               }
             }
       });
      

      });

      在隐藏的输入类型中添加了一个 id="token" 字段并使用 jquery 获取该值并将其作为 _token 字段传递到 ajax 请求数据中。这可以在使用 ajax 请求时得到纠正而不会出现任何 TokenMismatchException 错误。

      【讨论】:

        猜你喜欢
        • 2016-06-23
        • 2017-03-26
        • 2019-03-14
        • 2016-06-17
        • 2015-03-10
        • 1970-01-01
        • 2014-03-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多