从现有路由重定向到新路由

Redirect from existent route to a new one

如果用户未登录(与 FOSUser 和 SonataAdmin 一起使用)并调用 http://domain.com/app_dev.php (dev) 或 http://domain.com (prod),我将尝试重定向,然后我想要两者cases 重定向到 /login 所以我在 app/routing.yml:

写了这个配置
root:
    path: /
    defaults:
        _controller: FrameworkBundle:Redirect:urlRedirect
        path: /login
        permanent: true

可以,但是我有一个问题,因为我在控制器中有这个:

/**
 * @param Request $request
 *
 * @return array
 * @Route("/", name="brand")
 * @Method("GET")
 * @Template()
 */
public function indexAction(Request $request)
{
    ....
}

然后,当我尝试使用 link 调用 brand 路由时,例如:http://domain.com/app_dev.php/?email=7x-xRFClkjw (dev) 或 http://domain.com/?email=7x-xRFClkjw (prod) 我被重定向到/login。我最好的想法是将我的代码更改为:

/**
 * @param Request $request
 *
 * @return array
 * @Route("/bp", name="brand")
 * @Method("GET")
 * @Template()
 */
public function indexAction(Request $request)
{
    ....
}

然后 redirect using a route 到新的 /bp 而不是 / 用于该功能(这主要是因为用户已经有大量的电子邮件 links正如之前分享的那样,我无法更改)。但我不知道如何在 routing.yml 中编写此规则,因为如果我这样写:

bp:
    path: /
    defaults:
        _controller: FrameworkBundle:Redirect:redirect
        route: brand
        permanent: true

我将以重定向循环结束。我还可以更改到 /login 的默认路由的设置方式 我只是找不到正确的文档。 post 背后的重要思想是为 / 设置默认路由。任何人都可以给我一些帮助吗?

作为额外信息,这是我的 security.yml 文件的一部分:

firewalls:
    ...

    admin_area:
        pattern: ^/
        anonymous: ~
        form_login:
            provider: fos_userbundle
            csrf_provider: form.csrf_provider

            # the user is redirected here when they need to log in
            login_path: /login

            # submit the login form here
            check_path: /login_check

            # login success redirecting options (read further below)
            always_use_default_target_path: true
            default_target_path: /admin/dashboard
            target_path_parameter: _target_path
            use_referer: false
            failure_path: /admin/dashboard
            failure_forward: false
        logout:
            path:   /logout

更新

实际上来自@emmanuel-hdz-díaz 的代码给了我另一个想法,我不需要创建内核侦听器或添加太多代码,只需在我的控制器上执行此操作即可:

if ($request->query->get('email')) {
    ...
} else {
    return $this->redirect($this->generateUrl('sonata_user_admin_security_login'));
}

我能够将用户重定向到 /login 路由。

不确定我是否理解,但您想限制对整个网站的访问?在那种情况下,只需简单地更改您的安全设置,永远不要添加重定向到登录,因为即使用户已登录,它也总是重定向到登录。这是简单的配置示例:

security:
    firewalls:
        main:
            pattern: ^/
            anonymous: true

access_control:
    - { path: ^/login$, role: IS_AUTHENTICATED_ANONYMOUSLY }
    - { path: ^/, role: ROLE_USER }

试试这个:

在你的控制器里面 yourAction():

//

$usr = $this->get('security.context')->getToken()->getUser();

if( $usr == 'anon.' )
{
return $this->redirect($this>generateUrl('sonata_user_admin_security_login'));
}

//

抛出一个特殊异常,在 kernel.request 事件中捕获它,从那里重定向。 您必须创建一个自定义例外,您可以存储您的路线 in.e.g:

class RouteException extends \Exception{
    protected $route;

     public function __construct($route){
         $this->route = $route;
    }

    public function getRoute() { return $this->route; }
}

现在创建一个侦听器,当它检测到此异常时将生成 RedirectResponse,例如:

class RedirectExceptionListener{
  protected $router;

  public function __construct(RouterInterface $router){
    $this->router;
  }

  public function onException(GetResponseForExceptionEvent $event){

    $e = $event->getException();

    if($e instanceof RouteException){

      $url = $this->router->generate($e->getRoute());

      $event->setResponse(
        new RedirectResponse($url);
      );
    }
  }
}

# the service definition
your_listener:
    class: RedirectExceptionListener
    arguments:
        - @router
    tags:
        - { name: kernel.event_listener, event: kernel.exception, method: onKernelException }

注意:您必须use使用的命名空间类。
这基本上就是您可以从应用程序中的任何地方重定向的方法,尽管它看起来确实像是对异常的恶臭使用,因此创建一个服务 Redirecter 并使用一个方法 redirect($route) 为您抛出异常,因此调用服务不知道重定向是如何进行的 done.The Redirecter 可以抛出异常或执行重定向到给定路由所需的任何操作。
有关事件侦听器的更多信息,请参阅 Event Listeners.

更新:这正是 symfony 在您未通过身份验证时将您重定向到 login_path 的方式,请参阅 ExceptionListener