Search code examples
phpsessionlaravel-5google-authenticator

Laravel 5: How to store extra attributes to user login session


I'm actually implementing 2-factor auth into the project. What I did was

Auth::user()->google2fa_passed = 1;

In fact it doesn't really store, when navigate to another page, the value is missing.

I also don't want to keep in another session, because when user logout (or users remove the session cookie from their browser), then will show a login page, and go through the 2 factor auth again.

Any idea how to save 1 more attribute to user session?


Solution

  • Eventually, I use session to store.

    After key in the 6-digits code, store a flag into session

    \Session::put('totp_passed', 1);
    

    In app/Http/Middleware/Authenticate.php, remove the 2FA session if session expired

    public function handle($request, Closure $next)
    {   
        if ($this->auth->guest()) {
            // remove the 2-factor auth if the user session expired
            \Session::forget('totp_passed'); // <------- add this line
    
            if ($request->ajax()) {
                return response('Unauthorized.', 401);
            } else {
                return redirect()->route('auth.login');
            }   
        }
        return $next($request);
    }
    

    Then create another middleware, e.g. app/Http/Middleware/TwoFactorAuth.php

    namespace App\Http\Middleware;
    
    use Closure;
    
    class TwoFactorAuth
    {
        /** 
         * Handle an incoming request.
         *
         * @param  \Illuminate\Http\Request  $request
         * @param  \Closure  $next
         * @return mixed
         */
        public function handle($request, Closure $next)
        {   
            if (!\Session::has('totp_passed')) {
                return redirect()->route('auth.2fa');
            }   
    
            return $next($request);
        }   
    }
    

    In app/Http/Kernel.php

    protected $routeMiddleware = [ 
        'auth'       => \App\Http\Middleware\Authenticate::class,
        'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
        'guest'      => \App\Http\Middleware\RedirectIfAuthenticated::class,
        '2fa'        => \App\Http\Middleware\TwoFactorAuth::class, // <------ add this line
    ];
    

    How to use

    Route::group(['middleware' => 'auth'], function () {
        // must be login first only can access this page
        Route::get('2fa', ['as' => 'auth.2fa', 'uses' => 'Auth\AuthController@get2FactorAuthentication']);
        Route::post('2fa', ['uses' => 'Auth\AuthController@post2FactorAuthentication']);
    
        // add 2-factor auth middleware
        Route::group(['middleware' => '2fa'], function () {
            // all routes that required login
        }); 
    });