【问题标题】:Laravel 5.1 getting TokenMismatchException when cookies disabledLaravel 5.1 在禁用 cookie 时获取 TokenMismatchException
【发布时间】:2016-02-15 18:21:29
【问题描述】:

我的应用程序中有 RESTfull api,使用这样的 AJAX PUT 请求:

               $.ajax({
               method: "PUT",
               url: "/device/{{ $client->id }}",
               async: false,
               data: {
                        javascript_enabled: $('#javascript-enabled').text(),
                        cookies_enabled: $('#cookies-enabled').text(),
                        device_pixel_ratio: $('#device-pixel-ratio').text(),
                        screen_resolution: $('#screen-resolution').text(),
                        browser_window: $('#browser-window').text(),
                        local_time: $('#local-time').text(),
                        local_time_zone: $('#local-time-zone').text(),
                        _token: "{{ csrf_token() }}"
                      },
               success: function(data)
                        {
                             alert('success');                          
                        },
            error: function (jqXHR, textStatus, errorThrown)
                   {
                       alert( "Internal server error occurred.");
                   }
           });

当我在浏览器中启用 cookie 时,此代码可以正常工作。

但是,当我禁用 cookie 时,我得到“TokenMismatchException”。

我已经通过将这一行放在“App\Http\Middleware\VerifyCsrfToken”类中解决了这个问题:

protected $except = [
    'device/*'
];

有什么方法可以在不禁用对该路由的 csrf 检查的情况下解决这个问题?

【问题讨论】:

  • 为什么该特定请求没有 csrf 异常?
  • 这样做有没有安全漏洞。只要安全性完好,我实际上对这种方法没问题。
  • 是的,我给你详细一点

标签: ajax laravel-5 csrf


【解决方案1】:

只有当您的请求中存在csrf 令牌时,您才能验证令牌,否则您将采用类似这样的替代方式

创建一个您的应用程序能够识别的自己的令牌

就像有一个类似custom_token 的参数,你应该在

app\Http\Middleware\VerifyCsrfToken.php

提示:如果您使用print_r($request),您可以看到所有元素

您应该像这样验证您的自定义令牌

$paramExist=  $request->custom_token;
    #return parent::handle($request, $next);
        if(isset($paramExist))
        {
            $yourSpecialkey ='a2$%$'; #This to check whether the param has the value that you set
            if($paramExist==$yourSpecialKey)
            {
                return $next($request);
            }
            else
            {
                return parent::handle($request, $next);
            }

        }   
        else
        {
            return parent::handle($request, $next);
        }

我已经给了你这个临时匹配,你应该用你自己的方式来匹配/验证你的令牌。

【讨论】:

  • 是的,但这种方式 $yourSpecialkey 是硬编码的,不会改变。如果我没记错的话,Laravel csrf 令牌会重新生成以防止劫持?真正的问题是为什么它不能在禁用 cookie 的情况下工作?我的意思是 cookie 或不发送任何 cookie 令牌。
  • 没错,Laravel 不仅可以看到请求中的 _token,它还可以看到 header,如果你看到请求的 header,你可以找到 cookie,当你禁用 cookie 时,请求不会具有自动导致抛出异常的经过身份验证的标头。
  • 是的,但它会在请求中看到 _token 值。即使禁用了 cookie。
  • 它可能没有到达应用程序,不确定确切原因。如果要禁用它,请禁用内核或中间件中的 cookie 过滤器
  • PS:请在$request返回的数组中查看
猜你喜欢
  • 1970-01-01
  • 2016-03-10
  • 2015-11-14
  • 1970-01-01
  • 2017-11-06
  • 2017-01-20
  • 2016-06-29
  • 2016-03-03
  • 2016-01-02
相关资源
最近更新 更多