doupeng2253 2015-08-29 16:13
浏览 51
已采纳

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

I'm trying to redirect if a user is not logged in (works with FOSUser and SonataAdmin) and calls either http://domain.com/app_dev.php (dev) or http://domain.com (prod) then I want in both cases redirect to /login so I wrote this config at app/routing.yml:

root:
    path: /
    defaults:
        _controller: FrameworkBundle:Redirect:urlRedirect
        path: /login
        permanent: true

That works but I have a problem since I have this in a controller:

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

Then when I try to call brand route as per example using a link like: http://domain.com/app_dev.php/?email=7x-xRFClkjw (dev) or http://domain.com/?email=7x-xRFClkjw (prod) I got redirected to /login. My best idea is to change my code into this:

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

And then redirect using a route to the new /bp instead to / for that function (this is mainly because users already has a tons of emails that had links as the previously shared and I can't change that). But I've not idea in how to write this rule in routing.yml because if I wrote this:

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

I will end up with a redirect loop. I could change also how default route to /login is setup I just can't find the right documentation. The big idea behind this post is to setup default route for /. Can any give me some help on this?

As extra info this is part of my security.yml file:

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

UPDATE

Actually the code from @emmanuel-hdz-díaz give me another idea and I don't need to create a kernel listener or add to much code, simple by doing this at my controller:

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

I was able to redirect the user to the /login route.

  • 写回答

3条回答 默认 最新

  • dragam0217 2015-09-01 05:32
    关注

    Throw a special exception, catch it in the kernel.request event, redirect from there. You have to create a custom exception that you can store your route in.e.g:

    class RouteException extends \Exception{
        protected $route;
    
         public function __construct($route){
             $this->route = $route;
        }
    
        public function getRoute() { return $this->route; }
    }
    

    Now create a listener that will generate a RedirectResponse when it detects this exception, e.g:

    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 }
    

    Note: you have to use the namespaces for the used classes.
    This is basically what you can do to redirect from anywhere in your application, although it does seem like a smelly use of exceptions, so create a service Redirecter with a method redirect($route) that throws the exception for you, so the calling service will not know how the redirection is being done.The Redirecter can throw the exception or do anything required to redirect to the given route.
    For more info on event listeners see Event Listeners.

    Update: This is exactly how symfony redirects you to your login_path when you're not authenticated, see ExceptionListener

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(2条)

报告相同问题?

悬赏问题

  • ¥15 DIFY API Endpoint 问题。
  • ¥20 sub地址DHCP问题
  • ¥15 delta降尺度计算的一些细节,有偿
  • ¥15 Arduino红外遥控代码有问题
  • ¥15 数值计算离散正交多项式
  • ¥30 数值计算均差系数编程
  • ¥15 redis-full-check比较 两个集群的数据出错
  • ¥15 Matlab编程问题
  • ¥15 训练的多模态特征融合模型准确度很低怎么办
  • ¥15 kylin启动报错log4j类冲突