# Symfony CSRF 教程
> 原文: [http://zetcode.com/symfony/csrf/](http://zetcode.com/symfony/csrf/)
Symfony CSRF 教程展示了如何在 Symfony 应用中实现 CSRF 保护。
## Symfony
Symfony 是一组可重用的 PHP 组件和一个用于 Web 项目的 PHP 框架。 Symfony 于 2005 年发布为免费软件。Symfony 的原始作者是 Fabien Potencier。 Symfony 的灵感来自 Djanog,Spring 和 ROR 框架。
## CSRF
跨站点请求伪造(CSRF)是一种攻击,其中恶意用户试图使合法用户在不知情的情况下提交他们不打算提交的数据。 CSRF 攻击专门针对状态更改请求,而不是数据盗窃。 成功的 CSRF 攻击可以迫使用户执行状态更改请求,例如转移资金或更改其个人数据详细信息。
CSRF 保护的工作原理是在表单中添加一个隐藏字段,该字段包含仅应用和用户知道的值(令牌)。 这样可以确保用户(而非其他实体)正在提交给定的数据。
`symfony/security-csrf`组件提供`CsrfTokenManager`用于生成和验证 CSRF 令牌。 默认情况下,使用 Symfony 表单组件创建的表单包括 CSRF 令牌,Symfony 会自动检查它们,因此我们无需采取任何措施来防止 CSRF 攻击。 `csrf_token()` Twig 函数为用户呈现 CSRF 令牌。
## Symfony CSRF 保护示例
在下面的示例中,我们手动创建一个表单,为其实现 CSRF 保护。 在此应用中,我们在`routes.yaml`文件中定义路由。
```php
$ composer create-project symfony/skeleton csrf-app
$ cd csrf-app
```
使用`composer`,我们创建一个新的 Symfony 框架项目并定位到项目目录。
```php
$ composer require symfony/security-csrf
```
我们安装`security-csrf`软件包。
```php
$ composer require server --dev
```
我们安装开发 Web 服务器。
`config/routes.yaml`
```php
index:
path: /
controller: App\Controller\AppController::index
process-form:
path: /process
controller: App\Controller\AppController::processForm
```
我们为应用定义了两条路由。 `index`路由显示带有表单的主页。 `process-form`处理提交的表单并检查 CSRF 令牌。
`src/Controller/AppController.php`
```php
render('home/index.html.twig');
}
public function processForm(Request $request)
{
$token = $request->request->get("token");
if (!$this->isCsrfTokenValid('myform', $token))
{
return new Response('Operation not allowed', Response::HTTP_BAD_REQUEST,
['content-type' => 'text/plain']);
}
$name = $request->request->get("name");
$email = $request->request->get("email");
$msg = "$name with $email saved";
return new Response($msg, Response::HTTP_CREATED, ['content-type' => 'text/plain']);
}
}
```
`AppController`具有两个动作:`index()`和`processForm()`。
```php
public function index()
{
return $this->render('home/index.html.twig');
}
```
`index()`功能呈现主页。 主页包含 HTML 表单。
```php
$token = $request->request->get("token");
```
我们从请求中使用`get()`方法检索 CSRF 令牌。
```php
if (!$this->isCsrfTokenValid('myform', $token))
{
return new Response('Operation not allowed', Response::HTTP_BAD_REQUEST,
['content-type' => 'text/plain']);
}
```
我们使用`isCsrfTokenValid()`方法检查令牌的有效性。 如果令牌无效,我们将返回带有`Response::HTTP_BAD_REQUEST`代码的响应。 令牌`myform`的名称在模板的 HTML 表单中指定。
`templates/home/index.html.twig`
```php
{% extends 'base.html.twig' %}
{% block title %}Home page{% endblock %}
{% block body %}