MartynW
MartynW

Reputation: 709

How to redirect to external url in symfony 4 logout

Just wondering if there is an easy solution to this in Symfony 4. Normally users would logout and be sent back to the home page. But there is one page where it is checked that the user is currently authenticated on another site, if this is incorrect I have a link that logs the user out of my site and redirects to the external site. I managed this on an old silex based version of the site using the following routing of controllers in app.php

$app->get('/logout', $app->factory(function() use($app) {
$pid = $app['request_stack']->getCurrentRequest()->query->get('pid');
$message = $app['request_stack']->getCurrentRequest()->query->get('message');
$redirect = $app['request_stack']->getCurrentRequest()->query->get('redirect');
return $app->redirect(FRAMEWORK_URL."/logout?pid=$pid&message=$message&redirect=$redirect");
})

);

Thanks

Martyn

Upvotes: 2

Views: 3821

Answers (3)

Janusz Slota
Janusz Slota

Reputation: 383

Unfortunately logout.target will not work as there is special check (in Symfony\Component\Security\Http\HttpUtils::createRedirectResponse) to match the request domain to the redirection domain. If they're not the same it will set the target to /.

Proper way of redirecting to external URL is to create class which implements Symfony\Component\Security\Http\Logout\LogoutSuccessHandlerInterface, for example like this:

<?php

// src/Security/CustomLogoutSuccessHandler.php

class CustomLogoutSuccessHandler implements LogoutSuccessHandlerInterface
{
    private $target;

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

    public function onLogoutSuccess(Request $request)
    {
        return new RedirectResponse($this->target);
    }
}

Then create service in services.yaml:

services:
  App\Security\CustomLogoutSuccessHandler:
    arguments: ['%env(resolve:LOGOUT_TARGET_URL)%'] # resolve from .env (or you can get from anywhere)

and finally tell security.yaml to use your handler instead of default one:

security:
  firewalls:
    main:
      logout:
        success_handler: 'App\Security\CustomLogoutSuccessHandler'

Upvotes: 2

MartynW
MartynW

Reputation: 709

Ok so tried this

I made a new route in a controller:

    /**
 * @Route("/redirectafterlogout/{url?/}", name="redirectafterlogout")
 */
public function redirectafterlogout($url)
{
    if($url == "/"){
        // redirects to the "homepage" route
        return $this->redirectToRoute('homepage');
    } else {
        return $this->redirect('http://'.$url);
    }
}

I added this to security.yaml

logout:
            path:   logout
            target: 'redirectafterlogout'

it works fine and logs me out and puts me on the homepage if i use the normal logout link. However, if i try a link like:

it redirects me but does not seem to log me out? I can go back with me browser and I'm still logged in?

Not sure what I am doing wrong?

Thanks

Upvotes: 0

Andreas
Andreas

Reputation: 506

Set value of logout.target for a firewall in security.yaml to an external URL:

    firewalls:
        main:
                ...
            logout:
                ...
                target: 'EXTERNAL URL'

Value of logout.target could be an URL or app route name. App route and related controller could be used to create dynamic redirect targets.

Upvotes: 2

Related Questions