5

我遇到的问题是,当用户在登录页面中更改语言时 - 它可以工作,但在用户登录后 - 它再次恢复默认值。如何使登录前保持选择的相同语言用户成为可能,登录后保持不变?我试过在stackoverflow上查找这个,但找不到任何工作结果。

安全性.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

路由.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                

语言更改为:

<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>

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

4

1 回答 1

2

默认情况下,Security 组件将最后一个请求 URI(例如 )的信息保存在一个名为(其中定义为防火墙的名称/en/admin)的会话变量中。成功登录后,用户将被重定向到此路径,以帮助他们从他们访问的最后一个已知页面继续。_security.main.target_pathmainsecurity.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') 
            );
        }
    }
}

这会在使用当前语言环境登录后生成旧路由。

配置:

对于 Symfony 2:

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

对于 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');
    }
}

最后在你的包中注册编译器传递:

// src/AppBundle/AppBundle.php

class AppBundle extends Bundle
{   
    public function build(ContainerBuilder $container)
    {
        $container->addCompilerPass(new ExceptionListenerPass());
    }
}
于 2017-01-16T20:14:28.103 回答