Symfony3 saving locale after login

I have a problem when the user changes the language on the login page - it works, but after the user logs in, it returns to the default again. How to make it possible to save the same language that was selected by the user before entering the system, to remain after entering the system? I tried to look at this on stackoverflow, but could not find the result of work .

security.yml:

security: encoders: AppBundle\Entity\User: algorithm: bcrypt role_hierarchy: ROLE_ADMIN: ROLE_PREMIUM ROLE_PREMIUM: ROLE_USER providers: our_db_provider: entity: class: AppBundle:User property: email in_memory: memory: ~ firewalls: # disables authentication for assets and the profiler, adapt it according to your needs dev: pattern: ^/(_(profiler|wdt)|css|images|js)/ security: false main: anonymous: ~ form_login: #galima nurodyti kur nukreipia loginas login_path: login check_path: login csrf_token_generator: security.csrf.token_manager logout: path: /logout pattern: ^/ http_basic: ~ provider: our_db_provider access_denied_url: homepage 

routing.yml

 app: resource: "@AppBundle/Controller/" type: annotation prefix: /{_locale} requirements: _locale: lt|en|ru root: path: / defaults: _controller: FrameworkBundle:Redirect:urlRedirect path: /%locale%/ permanent: true login: path: /{_locale}/login defaults: { _controller: AppBundle:Security:login } requirements: _method: GET _locale: lt|en|ru logout: path: /logout defaults: _controller: FrameworkBundle:Redirect:urlRedirect path: /{_locale}/login permanent: true register: path: /{_locale}/register defaults: { _controller: AppBundle:Registration:register } requirements: _method: GET _locale: lt|en|ru 

Language changed:

 <ul class="top-menu-list top-menu-languages"> <li><a href="{{ path(app.request.attributes.get('_route'), app.request.query.all|merge({'_locale': 'lt'})) }}">LT</a></li> <li><a href="{{ path(app.request.attributes.get('_route'), app.request.query.all|merge({'_locale': 'en'})) }}">EN</a></li> <li><a href="{{ path(app.request.attributes.get('_route'), app.request.query.all|merge({'_locale': 'ru'})) }}">RU</a></li> </ul> 

Any ideas or examples would be appreciated!

+5
source share
1 answer

By default, the security component stores information about the last request URI (for example, /en/admin ) in a session variable named _security.main.target_path ( main is the firewall name defined in security.yml ). After a successful login, the user is redirected to this path to help them continue working from the last known page they visited.

Note. No matter how many times the language changes on the login page, since the firewall always redirects to /en/admin/ after a successful login, so the locale changes to en again.

To fix this, you may need to change the default behavior of the target path :

Exception Listener Class:

 // src/AppBundle/Security/Firewall/ExceptionListener.php use Symfony\Component\Security\Http\Firewall\ExceptionListener as BaseExceptionListener; class ExceptionListener extends BaseExceptionListener { use TargetPathTrait; protected function setTargetPath(Request $request) { if ($request->hasSession() && $request->isMethodSafe(false) && !$request->isXmlHttpRequest()) { $this->saveTargetPath( $request->getSession(), // the firewall name 'admin', // save the route name instead of the URI $request->attributes->get('_route') ); } } } 

This generates an old route after logging in with the current locale.

Configuration:

For Symfony 2:

 # app/config/services.yml parameters: # ... security.exception_listener.class: AppBundle\Security\Firewall\ExceptionListener 

For Symfony 3:

You may need to create a compiler run and manually modify this class:

 // src/AppBundle/DependencyInjection/Compiler/ExceptionListenerPass.php; class ExceptionListenerPass implements CompilerPassInterface { /** * {@inheritdoc} */ public function process(ContainerBuilder $container) { $definition = $container->getDefinition('security.exception_listener.admin'); $definition->setClass('AppBundle\Security\Firewall\ExceptionListener'); } } 

Finally, register the compiler pass in your bundle:

 // src/AppBundle/AppBundle.php class AppBundle extends Bundle { public function build(ContainerBuilder $container) { $container->addCompilerPass(new ExceptionListenerPass()); } } 
+3
source

Source: https://habr.com/ru/post/1262883/


All Articles