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?

Was it helpful?

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:

  1. http://localhost:8888/silex-skeleton/web/index_dev.php/login GET (redirect to login form)
  2. http://localhost:8888/silex-skeleton/web/index_dev.php/admin/login_check POST (authenticate)
  3. 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(.....)
});
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top