I was writing an extension where I need to inject additional cookies into the page after a user successfully login or registers, and found it to be incredibly complicated.
First there are the UserLoggedIn
and UserWasRegistered
events, but there is apparently no way to access the session, request or response from there, so no way to store anything in that user session or response.
Another option is to use a middleware to alter the request and response for /login
and /register
. But there doesn't seem to be a built-in way to access the logged in user in there. $request->getAttribute('actor')
is not updated after the controller has run, and still returns Guest
.
I found the following to work:
class LoginMiddleware implements MiddlewareInterface
{
public function __invoke(Request $request, Response $response, callable $out = null)
{
$response = $out ? $out($request, $response) : $response;
if (in_array($request->getUri()->getPath(), ['/login', '/register'])) {
// The actor attribute isn't automatically re-populated after the login/register
// However we can replicate the behaviour to get which user is logged in now
$session = $request->getAttribute('session');
$actor = User::find($session->get('user_id'));
// Do something with $actor
}
return $response;
}
}
My main concern about that solution is that I'm accessing some session data directly, and assuming the user_id
can be passed to find()
. If the core changes that, I'll have to update it here as well...
Shouldn't there be a way to access the actor/auth user after the controller has run ? Maybe the AuthenticateWithSession
middleware could run a second time after $out()
to check if the actor has changed and update it ? On the other hand the $request
is supposed to represent the state before the controller... Maybe there would be a way to attach a user to a response ? I'd make a PR but I really don't know what's best for this case.