如何为 Symfony3 上的 AJAX 调用添加 CSRF 保护?
Posted
技术标签:
【中文标题】如何为 Symfony3 上的 AJAX 调用添加 CSRF 保护?【英文标题】:How to add CSRF protection to AJAX call on Symfony3? 【发布时间】:2017-12-21 02:29:49 【问题描述】:我正在开发一个网站,您可以在其中“添加朋友”另一个用户,就像 facebook 一样。现在,我放了一个链接,当你点击它时,AJAX 调用就完成了。
在坚持新友谊之前,我检查请求是否是 Ajax,但我想更进一步并增加更多安全性。一个页面可以有超过 10 个链接(可能的请求),所以...我不知道我是只需要一个令牌,还是每个链接一个令牌。
另一个疑问是......如何使用 Symfony 生成令牌并检查是否有效?重点介绍如何在初始控制器上生成令牌,然后,如何在 addFriend 控制器(接收 ajax 调用)上进行验证。
我尝试使用它来生成令牌:
http://api.symfony.com/3.1/Symfony/Component/Security/Csrf/TokenGenerator/TokenGeneratorInterface.html
然后检查令牌:
https://symfony.com/doc/current/controller/csrf_token_validation.html
但始终返回令牌无效有效。
【问题讨论】:
将表单创建为普通的 Symfony 表单,然后将其加载到您的模板中并通过 ajax 发送表单。它将像任何其他 Symfony 表单一样拥有 CSRF 令牌 谢谢,但对我来说,为没有表单元素创建表单似乎是一种不好的做法。 它将有一个元素 - CSRF 令牌。它可能会有其他隐藏字段。这不是坏习惯,它以预期的方式使用 Symfony 框架 只需确保使用用于验证它的相同'token_id'
生成令牌。
如果你在树枝上下文中,你可以使用 csrf_token('token_id')
【参考方案1】:
我终于找到了解决问题的方法。
正如@yceruto 评论的那样,可以在没有任何形式的情况下生成csrf token
,请参见:http://symfony.com/doc/current/reference/twig_reference.html#csrf-token
有了这个,我可以通过以下方式在 TWIG 上创建我的链接:
<a data-id=" user.id " class="card-link clickable sendFriendRequest" data-token=" csrf_token(user.id) ">ADD_FRIEND</a>
然后,我像这样进行 AJAX 调用:
$('.elementsList').on('click','.sendFriendRequest', function ()
var userId = $(this).data('id');
var token = $(this).data('token');
$.post('/users/sendFriendRequest/'+userId, token: token
).done(function (response)
//Some code here
).fail(function (response)
);
);
最后,您使用以下代码检查令牌在您的控制器上是否有效:
$token = $request->request->get('token');
$isValidToken = $this->isCsrfTokenValid($townId, $token);
谢谢!
【讨论】:
$townId
是什么?那不是用来生成令牌的用户 ID 吗?
@Chris 我不知道他为什么要加$townId
,你只要把token的标识符加为函数的第一个参数就行了。因此,如果您像这样csrf_token('foobar')
创建您的令牌,那么您可以像这样检查它的有效性:$this->isCsrfTokenValid('foobar', $token)
对不起@Chris,我添加了对象ID,因为我有一个对象列表,所以我想为每个对象设置不同的令牌......这只是为了提高安全性。以上是关于如何为 Symfony3 上的 AJAX 调用添加 CSRF 保护?的主要内容,如果未能解决你的问题,请参考以下文章