Symfony国际化路由与安全访问控制适配问题求助
Great question! Dealing with internationalized routes alongside Symfony's Security component can feel clunky when you're repeating path configurations for every locale. Let's break down two key fixes to eliminate redundancy and handle locale-aware login/logout redirects automatically.
1. Replace Path-Based Access Control with Route Name Matching
Instead of listing every locale-specific URL in access_control, you can match routes by their name pattern (since your debug output shows routes like login.en, login.fr, etc.). This way, you don't have to update the security config every time you add a new locale or adjust a route's URL.
Here's how to rewrite your access_control section:
# ./config/packages/security.yaml access_control: # Allow anonymous access to the locale-free homepage - { path: ^/$, roles: IS_AUTHENTICATED_ANONYMOUSLY} # Match all login routes (login.en, login.fr, login.de) - { route: '^login\..*$', roles: IS_AUTHENTICATED_ANONYMOUSLY} # Match all password reset routes - { route: '^password_reset\..*$', roles: IS_AUTHENTICATED_ANONYMOUSLY} # Match all password forgot email routes (adjust regex to match your actual route names) - { route: '^email_send_password_forgot\..*$', roles: IS_AUTHENTICATED_ANONYMOUSLY} # Restrict admin paths to admins only - { path: ^/admin, roles: IS_ADMIN} # Require full authentication for all other paths - { path: ^/, roles: IS_AUTHENTICATED_FULLY}
The route parameter uses a regex pattern to match all routes whose names start with your base route name (e.g., login. followed by any locale code). This works because Symfony's internationalized routing appends the locale to the base route name automatically.
2. Use Route Names for Login/Logout Paths (No More Hardcoding!)
Instead of hardcoding locale-specific URLs for login_path, check_path, and logout.path, use the base route name. Symfony's router will automatically resolve this to the correct URL based on the current request's _locale parameter (or your default locale if none is set).
Update your firewall configuration like this:
# ./config/packages/security.yaml security: providers: # ... your existing providers ... firewalls: dev: # ... your existing dev firewall ... main: anonymous: true form_login: login_path: login # Uses the current locale's login route (e.g., login.fr → /fr/connexion) check_path: login # Same route handles the login form submission provider: my_provider logout: path: logout # Automatically uses the current locale's logout route guard: # ... your existing guard config ...
Now, when an unauthenticated user visits a protected page with a fr locale, they'll be redirected to /fr/connexion instead of the hardcoded /en/login. The same logic applies to logout—users will be sent to their locale's logout URL.
3. Verify Your Changes
To make sure everything works as expected:
- Run
php bin/console debug:securityto confirm youraccess_controlrules are matching the correct routes. - Test with different locales:
- Visit
/fr/some-protected-pagewhile logged out—you should redirect to/fr/connexion. - Log in, then trigger a logout—you should use the locale-specific logout path (like
/fr/deconnexion) based on your current locale.
- Visit
内容的提问来源于stack exchange,提问作者Vincent PHILIPPE

