Laravel jumps back to the page he visited before signing in

Keywords: PHP Session Laravel JSON

1. Jump to login page after Auth middleware check

That is, they fail the authentication check of the auth middleware, are intercepted by the auth middleware, and then jump to the login page.In this case, Laravel automatically jumps back to the page that was browsed before the user logged in by default.How does auth middleware do this?

Open the auth middleware file:

// vendor/laravel/framework/src/Illuminate/Auth/Middleware/Authenticate.php

protected function authenticate(array $guards)
{
    if (empty($guards)) {
          return $this->auth->authenticate();
    }

    foreach ($guards as $guard) {
        if ($this->auth->guard($guard)->check()) {
          return $this->auth->shouldUse($guard);
        }
    }

    throw new AuthenticationException('Unauthenticated.', $guards);
}

  

The auth middleware checks whether the user is authenticated by the authenticate() method and throws an exception if it is not.There is no jump to the login page, which means Laravel does further work after catching the exception.

Laravel handles this AuthenticationException in the exception handling class Illuminate\FoundationExceptionsHandler.Since the exception is included in the $internalDontReport property of the exception handling class, AuthenticationException exceptions do not need to be reported or written to the log; they only need to be handled as a response through the render() method.The unauthenticated() method is called in the render() method to handle AuthenticationException exceptions:

protected function unauthenticated($request, AuthenticationException $exception)
{
      return $request->expectsJson()
        ? response()->json(['message' => $exception->getMessage()], 401)
        : redirect()->guest(route('login'));
}

  

In the unauthenticated() method, first check if the request requires a Json response, and if not, execute the redirect ()->guest () method:

public function guest($path, $status = 302, $headers = [], $secure = null)
{
    $this->session->put('url.intended', $this->generator->full());

    return $this->to($path, $status, $headers, $secure);
}

  

In the redirected guest() method, the page address accessed by the user (but not authenticated) is first saved on the url.intended key of Session, and then redirected to the login interface.The Session url.intended key was created to jump after successful login.

Open the AuthenticatesUsers inherited from LoginController in the login controller AuthLoginController.php file.In this Trait, the login() method handles the login request, and after validation, calls the sendLoginResponse() method to return a response:

// vendor/laravel/framework/src/Illuminate/Foundation/Auth/AuthenticatesUsers.php

protected function sendLoginResponse(Request $request)
{
    $request->session()->regenerate();

    $this->clearLoginAttempts($request);

    return $this->authenticated($request, $this->guard()->user()) 
      ?: redirect()->intended($this->redirectPath());
}

  

In the final return of this method, you can see that if the return value of the authenticated() method is not true, the redirect ()->intended () method is executed.The authenticated() method is empty by default, so the redirect ()->intended () method must be executed:

// vendor/laravel/framework/src/Illuminate/Routing/Redirector.php

public function intended($default = '/', $status = 302, $headers = [], $secure = null)
{
    $path = $this->session->pull('url.intended', $default);

    return $this->to($path, $status, $headers, $secure);
}

  

The value of the Seesion url.intended key is checked in the redirected intended() method.If it has a value, it jumps to that address, which is the page that was visited but blocked by the Auth middleware.

The summary process is as follows:

Access to pages requiring authentication->Throw an exception after being blocked by the Auth middleware->Handle an exception: Save the address of the page you want to visit in the Session, then jump to the login page->Remove the previously saved page address from Session after successful login, and jump to that address.

2. Jump from the page without authentication to the login page

That is, the page you visit is public, accessible to users who are logged in or who are not logged in. Click the login button on this page to enter the login page.In this case, Laravel returns the root address of the domain name by default.Once you understand the Lararvel process in the first case, it's very simple to handle:

Simply override the showLoginForm() method in AuthLoginController.php, the Trait that it inherits from, AuthenticatesUsers:

// app/Http/Controllers/Auth/LoginController.php
use AuthenticatesUsers;

// Open the login page
public function showLoginForm()
{
    session(['url.intended'=>url()->previous()]);

    return view('auth.login');
}

  

Just add a line to the original showLoginForm() method!The key to this is to save the page address of the previous browse into the url.intended key of Session when you open the login page.

Since the login step is the same as the first case, Laravel checks the value of the Session url.intended key after successful login and jumps to the page if there is a value.

(finished)

Posted by bobcooper on Sat, 20 Jul 2019 10:09:54 -0700