Redirect after login succes + Silex
Question
What I'd like to do is check when someone is loggin in if they have a cookie. And when they have I want to redirect them to $cookie_data/dashboard
.
Because when you select a language on my server, a cookie is set. So I would like to redirect them to $language/dashboard
.
I now have:
$app['security.authentication.success_handler.secured_area'] = $app->share(function() use ($app) {
$request = $app['request'];
$cookies = $request->cookies;
if($cookies->has("language"))
{
return $app->redirect('/nl/dashboard');
}
});
But this gives me errors:
Warning: array_map(): An error occurred while invoking the map callback in /Applications/MAMP/htdocs/pst/vendor/silex/silex/src/Silex/Provider/SecurityServiceProvider.php on line 264
Fatal error: Uncaught exception 'RuntimeException' with message 'Accessed request service outside of request scope. Try moving that call to a before handler or controller.' in /Applications/MAMP/htdocs/pst/vendor/silex/silex/src/Silex/Application.php:141 Stack trace: #0 /Applications/MAMP/htdocs/pst/vendor/pimple/pimple/lib/Pimple.php(83): Silex\Application->Silex\{closure}(Object(Silex\Application)) #1 /Applications/MAMP/htdocs/pst/app/bootstrap.php(67): Pimple->offsetGet('request') #2 /Applications/MAMP/htdocs/pst/vendor/pimple/pimple/lib/Pimple.php(126): {closure}(Object(Silex\Application)) #3 /Applications/MAMP/htdocs/pst/vendor/pimple/pimple/lib/Pimple.php(83): Pimple::{closure}(Object(Silex\Application)) #4 /Applications/MAMP/htdocs/pst/vendor/silex/silex/src/Silex/Provider/SecurityServiceProvider.php(409): Pimple->offsetGet('security.authen...') #5 /Applications/MAMP/htdocs/pst/vendor/pimple/pimple/lib/Pimple.php(126): Silex\Provider\SecurityServiceProvider->Silex\Provider\{closure}(Object(Silex\Application)) #6 /A in /Applications/MAMP/htdocs/pst/vendor/silex/silex/src/Silex/Application.php on line 141
How can I make this work or what's the best practice?
Solution
I am not sure that this is correct, but I believe you have to return object of another instance, see this question for details (particularly the answer of igorw)
Another option is to intercept the AUTHENTICATION_SUCCESS event of the dispatcher, I tried the following:
$app['dispatcher']->addListener(AuthenticationEvents::AUTHENTICATION_SUCCESS
, function($authEvent) use ($app) {
$request = $app['request'];
$cookieKeys = $request->cookies->keys();
$app['monolog']->addInfo('Available cookies are: ' . implode(', ', $cookieKeys));
return $app->redirect('SOME_URL_HERE');
});
In the log I successfully see the cookies, there aren't any errors, but the redirect does not work either! After inspecting the logs (MONOLOG) I saw that the following routes are called on when trying to access my secured area which is /admin
:
http://localhost:8888/silex-skeleton/web/index_dev.php/login
GET (redirect to login form)http://localhost:8888/silex-skeleton/web/index_dev.php/admin/login_check
POST (authenticate)http://localhost:8888/silex-skeleton/web/index_dev.php/admin
GET (redirect back to originally requested url)
The authentication events are called on the intermediate /login_check
request and returning different values does not seem to have any impact on the overall result, at least I did not manage to do this. What I'm wondering is why don't you redirect in your ROUTE HANDLER function??? The result would be the same, at least if I understood the question correctly. For example put your code in the handler for the secured area, like:
$app->get('/dashboard', function() use ($app) {
$request = $app['request'];
$cookies = $request->cookies;
if($cookies->has("language"))
{
return $app->redirect('/nl/dashboard');
}
return new Response(.....)
});