提交登录表单后遇“_username必须为字符串,给定NULL”错误求助
问题原因及解决方案
核心问题
- 请求格式不匹配:你设置了
Content-Type: application/x-www-form-urlencoded,但请求体用JSON.stringify()生成了JSON字符串,Symfony的form_login无法解析这种格式的请求,导致_username字段无法被识别,最终传入NULL。 - 缺少CSRF令牌:你的
security.yaml中开启了enable_csrf: true,但请求中没有携带CSRF令牌,即使格式正确也会触发验证失败。 - 控制器语法错误:
return $this->json()语句缺少闭合括号,会导致代码执行报错。
修复步骤
1. 修正前端请求格式
将请求体改为x-www-form-urlencoded格式,同时添加CSRF令牌:
// 先确保页面中有CSRF令牌的meta标签(比如在Twig模板中添加): // <meta name="csrf-token" content="{{ csrf_token('authenticate') }}"> fetch('/signin', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', }, body: new URLSearchParams({ _username: "test@example.com", _password: "your_password", _csrf_token: document.querySelector('meta[name="csrf-token"]').content }) }) .then((res) => res.json())
2. 修复控制器语法错误
补上json()方法的闭合括号:
#[Route('/signin', name: 'app_login')] public function login(AuthenticationUtils $authenticationUtils): Response { if ($this->getUser()) { return $this->redirectToRoute('app_dashboard'); } $error = $authenticationUtils->getLastAuthenticationError(); $lastUsername = $authenticationUtils->getLastUsername(); return $this->json([ 'last_username' => $lastUsername, 'error' => $error ? $error->getMessage() : null, ]); // 补上缺失的闭合括号 }
3. (可选)如果想用JSON格式请求
如果更倾向于用JSON传递数据,需要在security.yaml中配置json_login替代或补充form_login:
security: firewalls: main: form_login: # 保留原有配置(如果需要支持传统表单登录) login_path: /signin check_path: /signin enable_csrf: true secure: auto json_login: check_path: /signin username_path: _username password_path: _password csrf_token_path: _csrf_token # 如果需要CSRF验证
此时前端请求改为:
fetch('/signin', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ _username: "test@example.com", _password: "your_password", _csrf_token: document.querySelector('meta[name="csrf-token"]').content }) }) .then((res) => res.json())
内容的提问来源于stack exchange,提问作者Plamena Zhelyazkova
相关产品推荐
相关产品推荐

