Bogdan Ivanov
Bogdan Ivanov

Reputation: 202

Redirect page Symfony

Programmers, faced with such problem. After the user authorization I want to redirect to a page with its data, but get an error. Here is the code

firewalls:
    main:
        pattern: /.*
        form_login:
            login_path: /
            check_path: /login_check
            default_target_path:  /user/{id}/show  //How to use the id of my controller. In routing i create it
            always_use_default_target_path: true
            use_referer:        true
        logout:
            path: /logout
            target: /
        security: true
        anonymous: true

Upvotes: 0

Views: 428

Answers (1)

Darragh Enright
Darragh Enright

Reputation: 14146

I assume that you want to redirect to a page and show the logged in user's data. I would suggest that it would be more straightforward to reroute to a non-dynamic route instead; e.g /user/show.

You don't need the id in the route in this case, because whatever route you redirect to, you will be able to get the authenticated user's object in the controller with:

class HomeController extends Controller
{
    /**
     * @Route("/user/show", name="user_show")
     * @Template()
     */
    public function userAction()
    {
        // do stuff...
        // send current user object to view
        return [
            'user' => $this->getUser(),
        ];
    }

I think this is the most straightforward approach, you already have the current user's context etc. otherwise - and I think you would need a very specific reason to use the user id here - you could implement a login handler, which would allow you to intercept a login event and run some custom code.

For completeness, you could do this as follows (not tested and not recommended in this case):

Create a user/{id}/show action in your controller, named user_show.

Then, in services.yml of your AppBundle (or equivalent) bundle:

app.event_listener.login_success_handler:
    class:  AppBundle\EventListener\LoginSuccessHandler
    arguments:
        - @router
    tags:
        - { name: 'login.handler', channel: 'security' }

Then create a AppBundle/EventListener/LoginSuccessHandler.php class:

<?php

namespace AppBundle\EventListener;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\Routing\Router;
use Symfony\Component\Security\Http\Authentication\AuthenticationSuccessHandlerInterface;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;

/**
 * LoginSuccessHandler
 */
class LoginSuccessHandler implements AuthenticationSuccessHandlerInterface
{
    public function __construct(Router $router)
    {
        $this->router   = $router;
    }

    /**
     * onAuthenticationSuccess
     *
     * @param  \Symfony\Component\HttpFoundation\Request                            $request
     * @param  \Symfony\Component\Security\Core\Authentication\Token\TokenInterface $token
     * @return \Symfony\Component\HttpFoundation\RedirectResponse
     */
    public function onAuthenticationSuccess(Request $request, TokenInterface $token)
    {
        $routeParams = [
            'id' => $token->getUser()->getId(),
        ];

        return new RedirectResponse($this->router->generate('user_show', $routeParams));
    }
}

Something like that. The goal here being that you:

  • Intercept the login success event
  • Get the authenticated user
  • Manually redirect

To reiterate, I have not tested the above code so YMMV. I don't see this approach is necessary in this case - login event handlers are useful if you need some specific and custom functionality on login success. However you can easily get the current User context in controllers, which covers most use cases in my experience.

Hope this helps :)

Upvotes: 1

Related Questions