如何在 Laravel 中禁用 CSRF 令牌以及为啥我们必须禁用它?

Posted

技术标签:

【中文标题】如何在 Laravel 中禁用 CSRF 令牌以及为啥我们必须禁用它?【英文标题】:How to disable CSRF Token in Laravel and why we have to disable it?如何在 Laravel 中禁用 CSRF 令牌以及为什么我们必须禁用它? 【发布时间】:2016-10-14 21:01:34 【问题描述】:

我想看看如何在 Laravel 中禁用 CSRF 令牌,以及我必须在哪里禁用它。禁用它好不好?

【问题讨论】:

【参考方案1】:

如果您想阻止 csrf 令牌验证,请轻松前往 app/Middleware/VerifyCsrfToken.php 为所有路由禁用它 protected $except = ['*']; 或指定这样的路线

 protected $except = ['/api/route/one', 'api/route/two'];

【讨论】:

【参考方案2】:

在 laravel 7 中。 打开文件\App\Http\Middleware\VerifyCsrfToken.php

禁用所有路由

protected $except = [
    '*',
];

对某些路线禁用

 protected $except = [
    'mobile/*',
    'news/articles',
];

找了半天如何彻底禁用CSRF,有很多相同的例子,但都无济于事

【讨论】:

禁用所有路线对于初学者学习非常有用。谢谢你 不,不是。你应该学会使用它。禁用它绝不应该是一种选择。 @rameezmeans 它应该。因为你认为他在做“错误”的事情而限制程序员是荒谬的,而且是一种雪花式的编程方法。 @Silidrone 好的。所以通过禁用中间件,我们必须招致安全风险? 如果一个人决定给自己的软件带来安全风险,无论如何,他们应该能够做到。劝阻它,我理解。不允许吗?我不同意。【参考方案3】:

许多人解释了如何做到这一点,但他们没有解释 url 应该是什么样子。

编辑app/Http/Middleware/VerifyCsrfToken.php

namespace App\Http\Middleware;

use Illuminate\Foundation\Http\Middleware\VerifyCsrfToken as Middleware;

class VerifyCsrfToken extends Middleware

    /**
     * Indicates whether the XSRF-TOKEN cookie should be set on the response.
     *
     * @var bool
     */
    protected $addHttpCookie = true;

    /**
     * The URIs that should be excluded from CSRF verification.
     *
     * @var array
     */
    protected $except = [
        '/user/my_function'
    ];

在 $except 数组();我们添加一个带有简单字符串的 url。这指向一个控制器,通常取决于你的路由是如何设置的。

例如,我的 Controller 文件夹中有一个 UserController.php 文件。我有一个类似的路线。在 web.php 路由文件中。

Route::post('/user', 'UserController@my_function')->name('my_function');

另外,如果您只是因为不知道如何使用 CSRF 而提出这个问题,并且您实际上不需要禁用它,或者将 URL 设为例外。你可以使用这个方法。

如果 app.blade.php 用于 ajax 相关调用,请将这些行添加到您的 app.blade.php。

<script>
$(function() 
    $.ajaxSetup(
        headers: 
        'X-CSRF-Token': $('meta[name="csrf-token"]').attr('content')
        
    );
);
</script>

【讨论】:

【参考方案4】:

您可以在web 中间件组中的app/http/Kernel.php 中禁用它。


这样禁用好不好?

不是。阅读Wikipedia page about CSRF了解什么是CSRF,CSRF-Token可以防止CSRF。

【讨论】:

如果我们必须使用多个 ajax 请求,那么它会在更改令牌值和不匹配时显示 505 内部服务器错误。这种情况下我们需要做什么? 当然,但是如果该功能不起作用或必须被黑客入侵,那有什么用处? 该功能按预期工作,不需要被破解,如果您有许多 ajax 请求,请考虑使用 api 路由、路由/ api.php 你不需要为它验证 csrf,csrf 令牌基本上可以防止从你的站点外部的表单到 web 路由的请求,从安全角度来看这是非常好的 @tkausl - 如何在“api”中间件组的 app/http/Kernel.php 中禁用它?我将 Laravel 5.7 用于移动 api,但是当我使用 post api 请求时,系统返回“对不起,您的会话已过期。请刷新并重试。”这意味着系统正在应用基于会话的 CSRF,我该如何避免呢?请提出建议。 请注意,在某些情况下可能需要禁用它。当然只用于开发,在生产中没有办法。在开发中,我在子目录中的同一本地域上使用更多 laravel 应用程序,例如domain.local/laravel-app1 + domain.local/laravel-app2 在这种情况下,我不能在浏览器中使用这两个应用程序,因为 CSRF 不匹配导致麻烦的错误 219 页面已过期。有趣的是,如果有人想在启用 CSRF 的生产环境中使用同一域上的两个不同的 laravel 应用程序,laravel 没有解决方案。我认为 CSRF cookie 名称和标头应该是可配置的。【参考方案5】:

临时修复。不推荐

只需打开 kernel.php (app/http) 并禁用

App\Http\Middleware\VerifyCsrfToken::class,

【讨论】:

请不要这样做 @simonhamp 您能否简要解释一下为什么不应该这样做,它值得提供信息。对其他用户也是如此。 CSRF 令牌生成和验证是针对常见攻击向量的可靠缓解措施 - 它有助于阻止您的 Web 表单被其他站点滥用。最常见的情况是有人对您的登录表单进行暴力强制登录尝试 - 使用 CSRF 令牌并打开此中间件,这作为攻击媒介变得不可行。像这样在整个站点范围内禁用它会为您的表单提供更多被滥用的机会。这是非常风险。如其他答案所述,最好使用 $except 数组在中间件中设置显式异常。 在开发过程中关闭安全功能是完全合法的。 请注意,在某些情况下可能需要禁用它。当然只用于开发,在生产中没有办法。在开发中,我在子目录中的同一本地域上使用更多 laravel 应用程序,例如domain.local/laravel-app1 + domain.local/laravel-app2 在这种情况下,由于 CSRF 不匹配导致麻烦的错误 219 页面已过期,我无法在浏览器中使用这两个应用程序。有趣的是,如果有人想在启用 CSRF 的生产环境中使用同一域上的两个不同的 laravel 应用程序,laravel 没有解决方案。我认为 CSRF cookie 名称和标头应该是可配置的。【参考方案6】:

CSRF 令牌可保护您的应用程序及其用户免受跨站点请求伪造的侵害。有关这方面的更多信息,请在此处阅读:

https://en.wikipedia.org/wiki/Cross-site_request_forgery

令牌通过 Laravel 中的中间件进行验证。如果您查看文件 app/Http/Middleware/VerifyCsrfToken.php,您会看到它为您提供了添加应该免于 CSRF 验证的 URL 的选项。

<?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 = [
        //
    ];

如果要完全禁用它,可以在app/Http/Kernel.php 中名为web 的中间件组中找到它。这些是默认通过 HTTP 请求触发的中间件。

我不建议在可能的情况下禁用它。

【讨论】:

请注意,在某些情况下可能需要禁用它。当然只用于开发,在生产中没有办法。在开发中,我在子目录中的同一本地域上使用更多 laravel 应用程序,例如domain.local/laravel-app1 + domain.local/laravel-app2 在这种情况下,由于 CSRF 不匹配导致麻烦的错误 219 页面已过期,我无法在浏览器中使用这两个应用程序。有趣的是,如果有人想在启用 CSRF 的生产环境中使用同一域上的两个不同的 laravel 应用程序,laravel 没有解决方案。我认为 CSRF cookie 名称和标头应该是可配置的。【参考方案7】:

您好,只需转到 app/Http/Kernel.php 文件,只需将第 31 行注释掉

// \App\Http\Middleware\VerifyCsrfToken::class,

【讨论】:

你不能禁用它。 你不应该那样做。【参考方案8】:

您可以通过编辑在少数路由上禁用 CSRF。

App\Http\Middleware\VerifyCsrfToken 

并在 protected 中添加您自己的路线名称

$except = [] array.

这似乎不是一个好的做法,因为这样做我们正在删除 Laravel 的安全功能。

【讨论】:

在我的 Laravel7 中,它是 URI,而不是路由名称(可怕的设计决策,但是...) @IceFire 在__construct 方法中,通过对数组中的每个元素使用route 帮助器将路由名称转换为URI 非常容易。

以上是关于如何在 Laravel 中禁用 CSRF 令牌以及为啥我们必须禁用它?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我在 laravel 中运行测试时收到“CSRF 令牌不匹配”?

禁用 Ajax 调用的 CSRF 保护 - 它有多糟糕?

如何使用 ajax 在 LARAVEL 中获取新的 CSRF 令牌

如何使用 CSRF 令牌发布到 Laravel API?

如何在 VueJS 文件中添加 Laravel CSRF 令牌? [复制]

如何在 vuejs 组件中使用 laravel csrf 令牌