直接访问登录表单时未设置会话 cookie,导致 CSRF 令牌无效
Posted
技术标签:
【中文标题】直接访问登录表单时未设置会话 cookie,导致 CSRF 令牌无效【英文标题】:Invalid CSRF token as a result of session cookie not being set when visiting login form directly 【发布时间】:2021-10-11 04:59:54 【问题描述】:在进一步调查后更新此帖子,以确保它专注于实际问题(现在也在:https://github.com/symfony/symfony/issues/42691 提出)
我的环境
我正在跑步:
Symfony 5.3.6 php 7.3 版 Debian 10 在 WSL2 上运行 本地主机上的 Symfony 开发服务器,通过同一台机器上的 Chrome 访问描述和我想要实现的目标
我正在尝试按照 Symfony 教程 (https://symfony.com/doc/current/security/form_login_setup.html) 实现安全登录表单。 我收到错误消息“无效的 CSRF 令牌”。在第一次登录尝试时,但不是在随后的登录尝试中。 在调试之后(使用 Xdebug 3),Symfony 似乎没有创建会话来链接 CSRF 令牌。复制步骤
使用symfony new test_project
创建了一个新的 Symfony 项目
使用composer require symfony/maker-bundle --dev
安装了制造商包
遵循安全设置指南 (https://symfony.com/doc/current/security.html) 第 1-2 节
按照本指南https://symfony.com/doc/current/security/form_login_setup.html 使用make:auth
命令生成登录表单
访问 https://localhost:8000/login
使用有效的用户名和密码对以及隐藏的预生成 CSRF 令牌提交登录表单
我期待的结果
注册用户可以登录 https://localhost:8000/login实际结果
访问https://localhost:8000/login时,没有设置cookie 在提交包含 CSRF 令牌的登录表单时,由于该请求没有 cookie,Symfony 找不到会话,因此自然找不到 CSRF 令牌 由于没有 CSRF 令牌,Symfony 抛出异常“Invalid CSRF 令牌。”。它的响应标头包括一个代表会话的 cookie(自动假设,因为我遵循了 Symfony 教程) 第二次提交登录表单时,由于请求标头中发送了一个 cookie,Symfony “找到”会话中的 CSRF 令牌,因此登录按预期工作【问题讨论】:
当表单从缓存加载时,我通常会遇到这个问题。例如,注销会在我的应用程序中再次打开登录页面,如果用户只是让该页面保持打开状态,直到他们下次想要登录时才会失败。您的响应标头或 .htaccess 中是否有任何缓存规则? 嗨@fun2life 感谢您的提示。我不相信我的响应标头中有任何缓存规则,我没有添加任何缓存规则,但是我该如何检查呢?关于 .htaccess 文件,我发现了以下文件:/home/lushawn/.cache/composer/.htaccess
/home/lushawn/.config/composer/.htaccess
/home/lushawn/.local/share/composer/.htaccess
所有这些文件中都写有“拒绝所有人”。这可能是个问题吗?
您能否尝试将您的 register.html.twig 表单更改为仅 " form_start(registrationForm) form_end(registrationForm) " 并查看它是否适用于自动渲染。还可以尝试将 SubmitType 添加到注册表单,而不是手动添加提交按钮。
不是直接在主题上而是开箱即用 Symfony 使用 PHP 的本地会话处理程序,它在我的 linux 系统上指向 /var/lib/php/sessions。如果需要,文档显示了如何将其指向 var/cache。清除它可能会有所帮助,但可能不会。看起来您使用了似乎对我有用的 make:auth 和 make:registration-form 命令。我假设您使用的是 Symfony 开发服务器?
您好@alexcm 感谢您的建议。我只是在注册表格上尝试过这个,我得到了更多奇怪的行为。在初次注册尝试时,我收到以下错误:Key "errors" for array with keys "value, attr, form, id, name, full_name, disabled, label, label_format, label_html, multipart, block_prefixes, unique_block_prefix, row_attr, translation_domain, label_translation_parameters, attr_translation_parameters, priority, cache_key, clicked" does not exist.
然后,如果我返回或导航到注册表单的链接并重新尝试注册,它可以工作...这也是可重复的
【参考方案1】:
在 Symfony 的 github 上发帖后,他们的回复帮助我发现了问题。 Here is my post for interest.
看来问题是我使用的 PHP 7.3 已经到了生命的尽头。我设法使我在 security.yaml 和 framework.yaml 中的所有原始配置设置保持不变,并让我自己的 Symfony 项目现在可以工作。然而,Symfony 中没有任何东西提醒我 PHP 7.3 将不兼容。
我做了什么
在this guide 之后升级到 PHP 8.0.10结果
我不再收到 CSRF 错误,而且我的登录功能在我自己的 Symfony 项目中都可以正常工作。【讨论】:
以上是关于直接访问登录表单时未设置会话 cookie,导致 CSRF 令牌无效的主要内容,如果未能解决你的问题,请参考以下文章
关闭会话时未删除移动浏览器(chrome、safari)cookie