tuupola/slim-basic-auth

There is a way to update request in callback ?

Ducatel opened this issue · 7 comments

Hi,

There is a way to add an attribute/header in the request in callback (or authenticator) method ?

Currently I did that in two steps:

  1. In authenticator when credentials are correct I set my attribute in session
  2. In a second middleware I check if the attribute exist in session and I set it to the request

So I would be nice if it's possible to update the request in this middleware.

Thanks for your help ;)

With 3.x branch yes. I hope to release it this week. See before and after handlers for examples.

Ah, very nice ;)
I will wait for this release.
Thanks for your work ;)

Ok, so I have tried with the version 3.0.0-RC5 but I cannot found how pass something between authenticator function and Before function.
Is it possible to do that ?

That is what I did actually

$app->add(new Tuupola\Middleware\HttpBasicAuthentication([
    ......
    "authenticator" => function (array $arguments) use ($container) {
        $credentialsManager = new CredentialsManager($container->get('logger'));
        if ($credentialsManager->login($arguments['user'], $arguments['password']) === false) {
            return false;
        }
        $GLOBALS['X-Service'] = $credentialsManager->getService(); // I want to remove that line which is not very proper
    },
    "before" => function (Request $request, Response $response, $arguments) {
        $service = $GLOBALS['X-Service'];
        unset($GLOBALS['X-Service']);
        return $request->withAttribute('X-Service', $service );
    },
 ....
]));

With before you can alter the PSR-7 request object. However authenticator receives only username and password as parameters. What are you trying to achieve?

As you can see in me sample, my CredentialsManager class does the authentication and can grab some extra data about the current credentials used.
I need to pass that extra data to the next middleware.

If the CredentialsManager can retrieve the service based on username then you could do something like:

$app->add(new Tuupola\Middleware\HttpBasicAuthentication([
    ...
    "authenticator" => function (array $arguments) use ($container) {
        $credentialsManager = new CredentialsManager($container->get('logger'));
        if ($credentialsManager->login($arguments['user'], $arguments['password']) === false) {
            return false;
        }
    },
    "before" => function (Request $request, Response $response, $arguments) use ($container) {
        $credentialsManager = new CredentialsManager($container->get('logger'));
        $service = $credentialsManager->getServiceByUser($arguments['user'])
        return $request->withAttribute('X-Service', $service );
    },
    ...
]));

Or if the credentials manager was in the container then something like this would probably work:

$app->add(new Tuupola\Middleware\HttpBasicAuthentication([
    ...
    "authenticator" => function (array $arguments) use ($container) {
        if ($container['credentialsManager']->login($arguments['user'], $arguments['password']) === false) {
            return false;
        }
    },
    "before" => function (Request $request, Response $response, $arguments) {
        $service = ($container['credentialsManager']->getService();
        return $request->withAttribute('X-Service', $service);
    }
    ...
]));

Yes, I have found the same first solution.
Thanks for you help ;)