[英]Symfony3 locale after login ( redirect to default locale)
我在Symfony版本3.1.10的Symfony项目中遇到问题。 我完成了这个项目的翻译,这是我与Symfony的第一次会面。
这是什么问题:我有两种语言DE和EN,默认语言是DE。 当有人进入登录页面或主页(也是登录表单)并切换到EN并输入登录名后,将其更改语言环境更改为/ de /默认语言。 我花了几天时间解决这个错误,确实需要帮助。 我尝试了一切,但仍然没有任何进展。
我遵循了Symfony文档,如何配置翻译,如何使用Sticky用户会话,并且创建了所有相同的东西,但是仍然存在bug。 我将在下面显示我的代码:
配置文件
imports:
- { resource: parameters.yml }
- { resource: security.yml }
- { resource: services.yml }
parameters:
locale: de
framework:
#esi: ~
translator: { fallbacks: ["%locale%"] }
default_locale: "%locale%"
app / config / routing.yml
fos_user:
resource: "@FOSUserBundle/Resources/config/routing/all.xml"
app:
resource: "@AppBundle/Controller/"
type: annotation
proreg:
path: /{_locale}/product/registration
defaults: { _controller: ProductRegistration\Controller\ProductRegistrationController::productRegistrationAction }
prolist:
path: /{_locale}/profile/products
defaults: { _controller: ProductRegistration\Controller\ProductRegistrationController::listAction }
prodel:
path: /{_locale}/profile/products/delete/{id}
defaults: { _controller: ProductRegistration\Controller\ProductRegistrationController::deleteAction }
proadd:
path: /{_locale}/product/register
defaults: { _controller: ProductRegistration\Controller\ProductRegistrationController::createAction }
app / config / security.yml
security:
providers:
fos_userbundle:
id: fos_user.user_provider.username_email
firewalls:
# disables authentication for assets and the profiler, adapt it according to your needs
dev:
pattern: ^/(_(profiler|wdt)|css|images|js)/
security: false
main:
pattern: ^/
form_login:
provider: fos_userbundle
login_path: fos_user_security_login
# csrf_token_generator: security.csrf.token_manager # Use form.csrf_provider instead for Symfony <2.4
always_use_default_target_path: false
logout: true
anonymous: true
# http_basic: ~
# http://symfony.com/doc/current/security.html#a-configuring-how-your-users-will-authenticate
# form_login: ~
# http://symfony.com/doc/current/cookbook/security/form_login_setup.html
encoders:
FOS\UserBundle\Model\UserInterface: bcrypt
role_hierarchy:
ROLE_ADMIN: ROLE_USER
ROLE_SUPER_ADMIN: ROLE_ADMIN
access_control:
- { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/admin/, role: ROLE_ADMIN }
- { path: ^/sso/login_check, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/sso/settoken, role: ROLE_ADMIN }
- { path: ^/profile/products, role: ROLE_ADMIN }
- { path: ^/product/registration, role: ROLE_ADMIN }
app / Resources / FOSUserBundle / all.xml
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
<import
resource="@FOSUserBundle/Resources/config/routing/security.xml"/>
<import
resource="@FOSUserBundle/Resources/config/routing/profile.xml"
prefix="/{_locale}/profile" />
<import
resource="@FOSUserBundle/Resources/config/routing/registration.xml"
prefix="/{_locale}/register" />
<import
resource="@FOSUserBundle/Resources/config/routing/resetting.xml"
prefix="/{_locale}/resetting" />
<import
resource="@FOSUserBundle/Resources/config/routing/change_password.xml"
prefix="/{_locale}/profile" />
</routes>
app / Resources / FOSUserBundle / security.xml
<?xml version="1.0" encoding="UTF-8" ?>
<routes xmlns="http://symfony.com/schema/routing"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/routing http://symfony.com/schema/routing/routing-1.0.xsd">
<route id="fos_user_security_login" path="/{_locale}/login" methods="GET POST">
<default key="_controller">FOSUserBundle:Security:login</default>
</route>
<route id="fos_user_security_check" path="/login_check" methods="POST">
<default key="_controller">AppBundle:Security:check</default>
</route>
<route id="fos_user_security_logout" path="/logout" methods="GET POST">
<default key="_controller">FOSUserBundle:Security:logout</default>
</route>
</routes>
src / AppBundle / Controller / DefaultController.php
<?php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\Security\Core\Security;
use Symfony\Bundle\SecurityBundle\SecurityBundle;
use Symfony\Component\HttpFoundation\Request;
use Doctrine\ORM\EntityManager;
class DefaultController extends Controller
{
/**
* @Route("/{_locale}", name="homepage", defaults={"_locale": "de"})
*/
public function indexAction(Request $request)
{
// replace this example code with whatever you need
return $this->render('default/index.html.twig', [
'base_dir' => realpath($this->getParameter('kernel.root_dir').'/..').DIRECTORY_SEPARATOR,
]);
}
src / AppBundle / Controller / SecurityController.php
<?php
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
// src/UserBundle/Controller/SecurityController.php
namespace AppBundle\Controller;
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Symfony\Component\HttpFoundation\Request;
use FOS\UserBundle\Controller\SecurityController as BaseController;
class SecurityController extends BaseController
{
public function loginAction(Request $request)
{
$response = parent::loginAction(request);
// ... do custom stuff
$errors->messageData = "Test";
$errors->messageKey = "test";
$error = $error ? $error : $errors;
return $this->renderLogin(array(
'last_username' => $lastUsername,
'error' => $error,
//'csrf_token' => $csrfToken,
'origin' => $request->get("origin")));
}
public function checkAction()
{
$response = parent::checkAction();
die ("<pre>" .print_r($response). "</pre>");
}
}
src / AppBundle / Event / LocaleListener.php
// src/AppBundle/LocaleListener.php
namespace AppBundle\Event;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
use Symfony\Component\HttpKernel\KernelEvents;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class LocaleListener implements EventSubscriberInterface
{
private $defaultLocale;
public function __construct($defaultLocale = 'de')
{
$this->defaultLocale = $defaultLocale;
}
public function onKernelRequest(GetResponseEvent $event)
{
$request = $event->getRequest();
if (!$request->hasPreviousSession()) {
return;
}
//print_r($request->get('_locale'));
// try to see if the locale has been set as a _locale routing parameter
if ($locale = $request->attributes->get('_locale')) {
$request->getSession()->set('_locale', $locale);
} else {
// if no explicit locale has been set on this request, use one from the session
$request->setLocale($request->getSession()->get('_locale', $this->defaultLocale));
}
}
public static function getSubscribedEvents()
{
return array(
// must be registered after the default Locale listener
KernelEvents::REQUEST => array(array('onKernelRequest', 15)),
);
}
}
登录表单
<form action="{{ path("fos_user_security_check") }}" method="post" id="login-form" class="col-xs-12">
<div class="content">
<h2>{{ 'index.login.regcust'|trans }}</h2>
<p>{{ 'index.login.haveaccount'|trans }}</p>
<ul class="form-list">
<li class="form_element">
<label for="email" class="required">{{ 'index.login.email'|trans }}<em>*</em></label>
<div class="input-box">
<input type="hidden" name="origin" value="{{ origin }}" />
<input type="hidden" name="_target_path" value="{{ path("setSSOToken") }}" />
<input type="email" name="_username" value="" id="username" class="input-text required-entry validate-email" title="{{ 'index.login.email'|trans }}">
</div>
</li>
<li class="form_element">
<label for="pass" class="required">{{ 'index.login.password'|trans }}<em>*</em></label>
<div class="input-box input-box-password">
<input type="password" name="_password" class="input-text required-entry" id="password" title="{{ 'index.login.password'|trans }}">
<!--a href="" class="f-left forgot-password">{{ 'index.login.forgot'|trans }}</a-->
</div>
</li>
</ul>
<p class="required required_hint">
<em>*</em> {{ 'index.login.required'|trans }}
</p>
</div>
<div class="buttons-set">
<div class="button_wrapper">
<button type="submit" class="button" title="Anmelden" name="send" id="send2"><span><span>{{ 'index.login.submit'|trans }}</span></span></button>
</div>
</div>
</form>
如果有人可以帮助我如何解决此问题,我将不胜感激。 谢谢
好的,我确定这与您的配置有关。 让我们以编程方式再尝试一次:
1)在src / AppBundle / Event / LocaleListener.php中更改
namespace AppBundle\Event;
至
namespace AppBundle\EventListener;
并确保已根据https://symfony.com/doc/3.1/session/locale_sticky_session.html进行注册:
services:
app.locale_listener:
class: AppBundle\EventListener\LocaleListener
arguments: ['%kernel.default_locale%']
tags:
- { name: kernel.event_subscriber }
2)移除
/{_locale}
从app / Resources / FOSUserBundle / security.xml中添加
prefix="/{_locale}"
至
<import
resource="@FOSUserBundle/Resources/config/routing/security.xml"
在app / Resources / FOSUserBundle / all.xml中。 这主要是为了将配置保留在一个地方。
3)确保你有
firewalls:
main:
form_login:
login_path: fos_user_security_login
check_path: fos_user_security_check
default_target_path: <your_desired_route>
logout:
path: fos_user_security_logout
在app / config / security.yml中使用语言环境。
4)在app / config / security.yml中,您应该为access_control定义正确的路径:
access_control:
- { path: ^/(en|de)/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/(en|de)/register, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/(en|de)/resetting, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/(en|de)/admin/, role: ROLE_ADMIN }
- { path: ^/(en|de)/sso/login_check, role: IS_AUTHENTICATED_ANONYMOUSLY }
- { path: ^/(en|de)/sso/settoken, role: ROLE_ADMIN }
- { path: ^/(en|de)/profile/products, role: ROLE_ADMIN }
- { path: ^/(en|de)/product/registration, role: ROLE_ADMIN }
包括语言环境。 否则,这些路径将不会受到防火墙的保护。 另外,您还应确保注册,重置和任何其他路由与FOSUserBundle中的路由相对应。
编辑
看起来这与另一个控制器有关,该控制器更改了FOSUserBundle的行为。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.