Unintuitive nature of Laravel’s viaRemember()

Mike Sirius
2 min readSep 17, 2020

--

A very particular problem on my hands — make sure we are not allowing access to a disabled user. The check (is user disabled or not) is performed against another service via API call.

Fairly simple task on the surface, but who does not like a good edge case?

Steve (our fictional character) has signed in with “Remember Me” (by default the cookie expired in +5 years). Two days later Steve’s account is disabled by the system administrator. Unsuspecting Steve comes back to the platform five days later, authentication process recognises a valid “Remember Me” cookie and allows access.

I trust this being not an issue for a proper authentication/authorisation package, not in my case, though — I was dealing with legacy.

I took the 1st stab at creating a route middleware. The logic was simple — if you have been allowed access viaRemember() then we check if your account is disabled. In a nutshell:

public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->viaRemember()) {
# is user disabled? API call to another service.
# yes, back to login and challenge for credentials.
} return $next($request);
}

To my surprise, viaRemember() in this case, was always returning false. As seen by this google-query, this is a fairly common “issue”. It seems a lot of coders finding themselves puzzled when it comes to Auth::viaRemember().

You’ll find the best answer here.

To summarise:

  • Auth::viaRemember() goes after Auth::check().
  • Nothing else is different when compared to credentials-driven authentication process/flow.

I took a 2nd stab at expanding an existing route middleware responsible for protecting routes from unauthorised access. In a nutshell:

public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
if (Auth::guard($guard)->viaRemember()) { # is user disabled? API call to another service.
# yes, back to login and challenge for credentials.
}

# original code.
}
return $next($request);
}

I did not like the end result, felt to “crowded”, which lead me to the 3rd and final stab.

A beauty with Auth::check() is that it will return true in both cases:

  • valid session cookie
  • valid “Remember Me” cookie.

These leads to a natural flow where viaRemember() is best to be used.

  1. As a result of valid Auth::check() we’ll have a successful authentication and thus
  2. an event will be fired which we can listen for App\Listeners\LogSuccessfulLogin and
  3. determinate if successful authentication was caused by “Remember Me” or not.
public function handle(Login $event)
{
if (Auth::guard($event->guard)->viaRemember()) {

# is user disabled? API call to another service.
# yes, back to login and challenge for credentials.
}
}

Conclusion.

If you need to determinate if successful authentication was caused by “Remember Me” do that as App\Listeners\LogSuccessfulLogin callback.

--

--

Mike Sirius
Mike Sirius

Written by Mike Sirius

Tech growth strategist with 25+ years in founding and scaling startups. Host of the "Mastering Tech Growth" podcast. Sharing my and industry leaders' insights.

Responses (1)