當(dāng)使用一個登錄表單時,您應(yīng)該確??梢缘钟?CSRF (跨站點請求偽造)。安全組件已經(jīng)對 CSRF 內(nèi)置支持。在這篇文章中,您將學(xué)習(xí)如何在登錄表單中使用它。
登錄 CSRF 并不是特別知名。如果您想要知道更多詳細(xì)信息,請參閱鍛造登錄請求。
首先,配置安全組件來讓它可以使用 CSRF 保護(hù)。安全組件需要 CSRF 令牌提供程序。您可以使用安全組件中默認(rèn)的提供程序:
YMAL:
# app/config/security.yml
security:
firewalls:
secured_area:
# ...
form_login:
# ...
csrf_provider: security.csrf.token_manager
XML:
<!-- app/config/config.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<srv:container xmlns="http://symfony.com/schema/dic/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:srv="http://symfony.com/schema/dic/services"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<config>
<firewall name="secured_area">
<!-- ... -->
<form-login csrf-provider="security.csrf.token_manager" />
</firewall>
</config>
</srv:container>
PHP:
// app/config/security.php
$container->loadFromExtension('security', array(
'firewalls' => array(
'secured_area' => array(
// ...
'form_login' => array(
// ...
'csrf_provider' => 'security.csrf.token_manager',
)
)
)
));
可以進(jìn)一步配置安全組件,但這必須要能夠在登錄表單中使用 CSRF 攻擊所需的所有信息。
既然該安全組件將檢查 CSRF 令牌,您必須向包含 CSRF 令牌的登錄表單中添加隱藏的字段。默認(rèn)情況下,此字段被命名為 _csrf_token。該隱藏的字段必須包含 CSRF 令牌,該令牌可以使用 csrf_token 函數(shù)生成。該函數(shù)需要一個令牌的 ID,并且當(dāng)使用登陸表單的時候該 ID 必須用來進(jìn)行身份驗證:
Twig:
{# src/Acme/SecurityBundle/Resources/views/Security/login.html.twig #}
{# ... #}
<form action="{{ path('login_check') }}" method="post">
{# ... the login fields #}
<input type="hidden" name="_csrf_token"
value="{{ csrf_token('authenticate') }}"
>
<button type="submit">login</button>
</form>
PHP:
<!-- src/Acme/SecurityBundle/Resources/views/Security/login.html.php -->
<!-- ... -->
<form action="<?php echo $view['router']->generate('login_check') ?>" method="post">
<!-- ... the login fields -->
<input type="hidden" name="_csrf_token"
value="<?php echo $view['form']->csrfToken('authenticate') ?>"
>
<button type="submit">login</button>
</form>
經(jīng)過上述步驟,您已經(jīng)可以防御 CSRF 攻擊您登錄表單了。
您可以通過設(shè)置 csrf_parameter 來更改字段的名稱并通過在您的配置中設(shè)置意愿來更改令牌 ID :
YAML:
# app/config/security.yml
security:
firewalls:
secured_area:
# ...
form_login:
# ...
csrf_parameter: _csrf_security_token
intention: a_private_string
XML:
<!-- app/config/config.xml -->
<?xml version="1.0" encoding="UTF-8" ?>
<srv:container xmlns="http://symfony.com/schema/dic/security"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:srv="http://symfony.com/schema/dic/services"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<config>
<firewall name="secured_area">
<!-- ... -->
<form-login csrf-parameter="_csrf_security_token"
intention="a_private_string" />
</firewall>
</config>
</srv:container>
PHP:
// app/config/security.php
$container->loadFromExtension('security', array(
'firewalls' => array(
'secured_area' => array(
// ...
'form_login' => array(
// ...
'csrf_parameter' => '_csrf_security_token',
'intention' => 'a_private_string',
)
)
)
));