Symfony 3.4重写FOS User Bundle控制器遇CSRF令牌错误求助
Hey there! Let’s work through this CSRF token error you’re hitting when customizing the loginAction for FOSUserBundle in Symfony 3.4. I’ve dealt with this exact scenario before, so here’s the breakdown of what’s happening and how to fix it.
Why This Happens
When you copied the entire SecurityController from the vendor directory into your custom bundle, you might have broken the built-in CSRF token handling that FOSUserBundle relies on. The bundle uses a specific CSRF token ID (authenticate) and has its own service setup for managing these tokens—if your copied controller isn’t properly accessing that setup, the token generated in your form won’t match what Symfony expects during validation.
Step-by-Step Fixes
1. Don’t Copy the Entire Controller—Extend It Instead
Instead of duplicating the whole SecurityController, just inherit from the FOSUserBundle version and override only the loginAction. This way you reuse all the existing CSRF (and other) logic without breaking anything:
namespace MyVendor\MyVendorFOSUserBundle\Controller; use FOS\UserBundle\Controller\SecurityController as BaseSecurityController; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; class SecurityController extends BaseSecurityController { /** * @Route("/login", name="fos_user_security_login") */ public function loginAction(Request $request) { // Add your custom logic here (e.g., modify the request, add flash messages) // Call the parent method to handle the core login flow (including CSRF) $response = parent::loginAction($request); // Optional: Customize the response before returning it // $response->headers->set('X-Custom-Header', 'Value'); return $response; } }
2. Verify CSRF Token in Your Template
If you’re using a custom login template, make sure you’re generating the CSRF token with the correct ID that FOSUserBundle expects (authenticate):
{# In your login template #} <form action="{{ path('fos_user_security_check') }}" method="post"> <!-- Your other form fields --> <input type="hidden" name="_csrf_token" value="{{ csrf_token('authenticate') }}" /> <button type="submit">Login</button> </form>
Using the wrong token ID is the most common cause of this error—double-check that this matches exactly.
3. Ensure Proper Service Injection (If You Must Use a Standalone Controller)
If you really don’t want to inherit the base controller, make sure your custom controller has access to the CSRF token manager and uses the correct token ID:
namespace MyVendor\MyVendorFOSUserBundle\Controller; use Symfony\Bundle\FrameworkBundle\Controller\Controller; use Symfony\Component\HttpFoundation\Request; use Symfony\Component\Routing\Annotation\Route; use Symfony\Component\Security\Csrf\CsrfTokenManagerInterface; class SecurityController extends Controller { private $csrfTokenManager; public function __construct(CsrfTokenManagerInterface $csrfTokenManager) { $this->csrfTokenManager = $csrfTokenManager; } /** * @Route("/login", name="fos_user_security_login") */ public function loginAction(Request $request) { // Your custom logic $csrfToken = $this->csrfTokenManager->getToken('authenticate')->getValue(); return $this->render('@MyVendorFOSUser/Security/login.html.twig', [ 'csrf_token' => $csrfToken, // Other variables needed for the template ]); } }
Then in your template, use the passed csrf_token variable for the hidden input.
Final Checks
- Confirm your route name is exactly
fos_user_security_login—this ensures the form submits to the correct endpoint and the CSRF validation context matches. - Clear your Symfony cache with
php bin/console cache:clear(especially important in dev mode) to make sure all route and service changes take effect.
That should resolve the "Invalid CSRF token" error and let you customize the loginAction without breaking core functionality!
内容的提问来源于stack exchange,提问作者Med Karim Garali

