Symfony3登录后保持语言环境

Jus*_*asT 5 php symfony symfony-3.1

我遇到的问题是,当用户在登录页面中更改语言时 - 它可以工作,但在用户登录后 - 它又恢复为默认状态.如何在登录前保持同一语言用户的选择,登录后留下来?我已经尝试在stackoverflow上查找,但无法找到任何工作结果.

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
Run Code Online (Sandbox Code Playgroud)

使用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                
Run Code Online (Sandbox Code Playgroud)

语言改变了:

<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>
Run Code Online (Sandbox Code Playgroud)

任何想法或例子将不胜感激!

yce*_*uto 2

默认情况下,安全组件将最后一个请求 URI(例如 )的信息保留/en/admin在名为 的会话变量_security.main.target_pathmain是防火墙的名称,在 中定义security.yml)中。成功登录后,用户将被重定向到此路径,以帮助他们从上次访问的已知页面继续。

注意:无论登录页面更改多少次语言,由于防火墙总是/en/admin/在登录成功后重定向到,因此语言环境再次更改为en.

要解决此问题,您可能需要更改默认的目标路径行为

异常监听器类:

// 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') 
            );
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

使用当前区域设置登录后,这会生成旧路由。

配置:

对于 Symfony 2:

# app/config/services.yml
parameters:
    # ...
    security.exception_listener.class: AppBundle\Security\Firewall\ExceptionListener
Run Code Online (Sandbox Code Playgroud)

对于 Symfony 3:

您可能需要创建编译器通道并手动更改此类:

// 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');
    }
}
Run Code Online (Sandbox Code Playgroud)

最后在你的包中注册编译器通道:

// src/AppBundle/AppBundle.php

class AppBundle extends Bundle
{   
    public function build(ContainerBuilder $container)
    {
        $container->addCompilerPass(new ExceptionListenerPass());
    }
}
Run Code Online (Sandbox Code Playgroud)