Symfony 2 在使用没有类的表单时添加 CSRF 令牌

Posted

技术标签:

【中文标题】Symfony 2 在使用没有类的表单时添加 CSRF 令牌【英文标题】:Symfony 2 Add CSRF Token when using a form without a class 【发布时间】:2013-04-14 17:02:47 【问题描述】:

首先,我完全是 Symfony 2 的菜鸟。这个问题听起来很简单,如果我尝试将一些上下文说明我为什么需要它以及如何需要它,它就会开始变得混乱。

本质上,我创建了一个表单,我使用 Doctrine 等手动处理、验证和插入该表单。我在控制器操作中手动创建表单(它是从另一个对象的检索值动态构建的)。我假设可能有更好的方法来做到这一点,但由于我是 Symfony 的新手,并且在网上拖网的日子,我看不到任何我需要做的事情的解决方案。

因此,我不只是针对类/实体等构建表单,因此我需要手动添加 CSRF 令牌或某种保护。

在正常情况下,您将创建 FormType 并将默认选项配置为具有 csrf_protection。然后是一个简单的案例:

 form_widget(form._token) 

csrf 令牌就在那里。

当我动态构建表单时,我不确定如何为我的表单手动创建 csrf 令牌。有没有人有过创建没有类的表单并添加 csrf 保护的经验?

亲切的问候 保罗·庞德

【问题讨论】:

【参考方案1】:

我认为您正在寻找的是以下内容:

这将呈现一个 CSRF 令牌。如果您想在不创建表单的情况下进行 CSRF 保护,请使用此功能

 csrf_token("intention") 

例如:

<a href=" path('remove_stuff', token: csrf_token('intention')) ">Remove</a>

source

要从控制器验证此令牌,您可以:

if ($this->get('token') !== $this->get('security.csrf.token_manager')->getToken('intention')->getValue()) 
    throw new \Symfony\Component\Security\Core\Exception\InvalidCsrfTokenException('Invalid CSRF token');

为了简化在 Symfony 2.6 或更高版本上检查令牌

if ($this->isCsrfTokenValid('intention', $submittedToken)) 
    // ... do something, like deleting an object
  

【讨论】:

csrf_token 的参数是什么?表格的名称? @fain182 这是您的 csrf 令牌的一种过滤器,因此只有知道此 ID 的控制器/页面才会验证您的 csrf 令牌。更多信息:api.symfony.com/2.3/Symfony/Component/Form/Extension/Csrf/…【参考方案2】:

Form Type与token的关联:

 csrf_token("task_item_intention") 

在表单类型中:

class TaskType extends AbstractType

// ...

public function setDefaultOptions(OptionsResolverInterface $resolver)

    $resolver->setDefaults(array(
        'data_class'      => 'Acme\TaskBundle\Entity\Task',
        'csrf_protection' => true,
        'csrf_field_name' => '_token',
        // a unique key to help generate the secret token
        'intention'       => 'task_item_intention',
    ));


// ...

【讨论】:

对于 Symfony2.7+,在默认选项中使用 csrf_token_id 而不是 intention。查看下面的链接以获取更多信息。您也可以跳过csrf_protectioncsrf_field_name,因为它们的默认配置方式与您在上面看到的相同。 symfony.com/doc/current/form/csrf_protection.html【参考方案3】:

在(我的)正常情况下,您创建一个表单并且专门配置 CSRF - 它会自动发生,并且您使用 form_rest(form)form_end(form) 使用 CSRF 令牌呈现隐藏的输入。我不认为这对于没有模型支持的表单有什么不同。

【讨论】:

这是正确的 :) 是否动态构建表单并不重要。默认情况下,所有表单都启用 CSRF 保护。 我可以在不使用 Symfony 表单生成器时生成 CSRF-Token 吗? (因为我喜欢手动构建表单) Gigala:这是一个完全不同的话题,需要提出一个新问题;)

以上是关于Symfony 2 在使用没有类的表单时添加 CSRF 令牌的主要内容,如果未能解决你的问题,请参考以下文章

Symfony2 - 重载注册表单导致 CSRF 错误(添加 github repo)

向 Symfony 2 表单元素添加错误

Symfony2 - 动态生成的表单在编辑表单时不起作用

Symfony 5 表单通知:App\Entity\Epic 类的对象无法转换为 int

Symfony 2:添加自定义表单元素,而不是在实体中

Symfony表单 - 自动将固定数量的子项添加到集合中