Redirect after login

I’m following the documentation for authentication using mezzio-authentication-session that lives here:
https://docs.mezzio.dev/mezzio-authentication-session/v1/login-handler/

It works to log me in, but it doesn’t appear to properly redirect to the address I was at before the /login redirect

so for example,

  1. I go to mydomain.com/api/test
  2. It creates a session in the SessionMiddleware
  3. I see that the request->uri->path is ‘/api/test’
  4. It calls the AuthenticationMiddleware callable, which fails to authenticate, naturally, returning an unauthorizedResponse.
  5. This causes the a 302 Found response with a Location header of /login. There is no Referer Header
  6. The browser calls /login automatically
  7. It looks for the referer, and doesn’t find one. defaults to ‘/’
  8. It returns the login page to browser
  9. I fill out login form, and POST it
  10. Login succeeds and forwards the request to /

Is it the responsibility of the browser to send a Referer header or is it the responsibility of Mezzio to somehow tell the browser to submit it with the request to the new location?

If it is the responsibility of Mezzio, what am I missing from my code (I’m guessing I have to set the redirect into the session), and where should it go? LoginHandler is where I would expect, but it doesn’t get that far - it fails to authenticate first… but since it is redirecting to the login page, it appears to be behaving as expected. So, I’m not sure changing my pipeline order will help, though I have tried swapping the RouteMiddleware and the callable for the AuthenticationMiddleware, but it didn’t seem to help. Perhaps I should set it in the callable before it calls the AuthenticationMiddleware, but I don’t know. I feel like this should work just from the documentation example, since it specifically calls out the use case:
“Create a handler that will both display and handle a login form, redirecting to the originally requested location once a successful authentication occurs.”

$app->pipe(\Mezzio\Session\SessionMiddleware::class);
$app->pipe($factory->callable(
    function ($request, $handler) use ($container) {
        if ($request->getUri()->getPath() === '/login') {
            return $handler->handle($request);
        }
        $authenticationMiddleware = $container->get(
            Mezzio\Authentication\AuthenticationMiddleware::class
        );
        return $authenticationMiddleware->process($request, $handler);
    }
));
$app->pipe(RouteMiddleware::class);

Browser, which means that the information may be missing.

Does that mean that the PhpSession’s unauthorizedResponse needs to be sending a Referer header as well as a Location header?

public function unauthorizedResponse(ServerRequestInterface $request): ResponseInterface
{
    return ($this->responseFactory)()
        ->withHeader(
            'Location',
            $this->config['redirect']
        )
        ->withStatus(302);
}

Setting the Referer header didn’t work, because the browser will not forward the Referer to the following request to /login.

What appears to have worked, is adding the following to the PhpSession class’s unauthorizedResponse method:

$session  = $request->getAttribute('session');
$session->set('authentication:redirect', $request->getUri()->getPath());

This behaviour is correct.

Unfortunately, the idea is wrong. Editing the core files is a no-go and not needed.

Please check the handleLoginAttempt method of the login handler if you can set the variable there.
And before that you can check if the variable is already set.