Laravel在API中间件上启用CSRF保护。

7
我正在使用Laravel 5.4,并且我的路由在api中间件中。我发现需要将我的路由转移到web中间件,但是由于我正在创建RESTful API,因此需要它们保留在api中间件中。你有什么建议如何在api中间件中使用csrf?

@Ohgodwhy 我正在使用 Laravel 5.4。 - kdyz
@api中间件 - kdyz
将其放置在Web中间件中(我假设你的主要路由是Web组的一部分?请检查routes/web.php),你可能只是从那里将其删除了。 - apokryfos
这没有意义。为什么你需要将路由从API移动到Web,但仍然在API中保留它们?你能告诉我们你真正想做什么吗? - sisve
请查看此链接:https://dev59.com/VaDia4cB1Zd3GeqPK-Nd#43525110 - Pankit Gami
显示剩余4条评论
3个回答

11

CSRF保护可以防止攻击先前经过身份验证的用户(通常使用会话设置状态)https://www.owasp.org/index.php/Cross-Site_Request_Forgery_(CSRF)

Restful API没有状态https://en.wikipedia.org/wiki/Representational_state_transfer,因此没有会话可供攻击。因此,在restful API中,CSRF保护是对每个请求进行用户身份验证。如果您只对第一个请求进行身份验证,并在后续请求中使用会话,则不是在创建restful API,而应使用Web中间件。

编辑: 如果没有任何状态,您将如何将CSRF令牌传递给客户端?


1
是的,没有会话可以攻击,但问题在于您将令牌存储在哪里?以及如何保护它免受XSS攻击? - Wanny Miarelli

3

您可以在任何路由组中使用任何中间件,包括自定义中间件。Laravel为我们提供了非常方便的方式。只需打开App\Http命名空间中的Kernel.php文件。找到可能位于第28行附近的protected $middlewareGroups代码,并像下面那样更改代码以允许在API路由中启用Csrf保护:

protected $middlewareGroups = [
    'web' => [
        \App\Http\Middleware\EncryptCookies::class,
        \Illuminate\Cookie\Middleware\AddQueuedCookiesToResponse::class,
        \Illuminate\Session\Middleware\StartSession::class,
        // \Illuminate\Session\Middleware\AuthenticateSession::class,
        \Illuminate\View\Middleware\ShareErrorsFromSession::class,
        \App\Http\Middleware\VerifyCsrfToken::class,
        \Illuminate\Routing\Middleware\SubstituteBindings::class,
    ],

    'api' => [
        'throttle:60,1',
        'bindings',
        \App\Http\Middleware\VerifyCsrfToken::class,
    ],
];

是的,我们可以添加中间件,但是您的解决方案会引发错误,因为API是无状态的,所以会显示没有会话。 - kazemm

0

请确保您的 Web 中间件组包含以下行,并使用相同版本的干净 Laravel 安装验证内容。

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

并验证路由是否使用了Web中间件。 运行 php artisan route:list 命令,并注意中间件列。


我正在API中间件上。 - kdyz
默认情况下,CSRF仅适用于Web路由。因为API不使用CSRF令牌。如果您强制要在API上启用CSRF检查,则可以将\App\Http\Middleware\VerifyCsrfToken::class添加到您的API中间件组中。 - Sandeesh
已经完成了这个操作,现在在POST请求时出现了“请求中未设置会话存储”的错误提示 -> 我也将以下内容添加到API中间件组中:"\App\Http\Middleware\EncryptCookies::class, \Illuminate\Session\Middleware\StartSession::class,"。 - kdyz
@kdyz,我看到了你的编辑,这是我的想法。 这些API不应该使用会话,并且由于通常使用令牌对API进行身份验证,因此无需使用csrf令牌。 如果API是公共的且没有任何身份验证,则我认为也没有强制执行csrf检查的必要,因为任何人都可以使用它。 最终,我认为你没有理由对API强制执行csrf检查。 - Sandeesh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接