Laravel Multiauth: Different Versions - Different Strategies

May 21, 2016

Out Of Date Warning

This article was published on 21 May 2016, this means the content may be
out of date or no longer relevant. You should verify that the technical information in this article is still current before relying upon it for your own purposes.

In Laravel application that I’m currently working on, we have decided to implement login and registration
for our clients. But we have already implemented auth for our admins, that are placed in a
different table. We didn’t want to change out database schema: to move all entities to one table, or
to add different flags and so one. We just needed two auth implementations: one for clients and one
for admins.

Laravel 5.1

After some research we arrived at Laravel’s
Authentication Documentation, that told us to extend basic Auth class, and then switch to this new driver in
config/auth.php file.

In our case, we want to create another implementation of EloquentUserProvider that will use clients table to receive users.
Ok, but how to extend? Where to put all of this code?

Extend AuthManager

Laravel components may be extended in two different ways: binding a new implementation in Laravel IoC container, or registering an
extension with a Manager class. For managing creation of driver-based components, there are several special Manager classes. They
are implementations of the “Factory” design pattern, which create a particular driver implementation for a component, based on
the application’s configuration.
Each manager class has an extend method for injecting new driver implementation into the manager.

In our example, we are interested in AuthManager. To add a new driver resolution functionality into it we need to use already
know extend method:

<?phpAuth::extend('clientEloquent',function($app){// We need to return here an implementation of Illuminate\Auth\UserProviderInterface
});

In extend method we must return our new driver for clients table, let’s name it clientEloquent. Now we should create
this driver. Driver implementation must implement UserProviderInterface, which is responsible for fetching UserInterface
implementations out of a persistent storage system. In our case UserInterface implementations will be Eloquent models, and
we will use EloquentUserProvider as an implementation of UserProviderInterface.

EloquentUserProvider requires an instance of HasherContract for password cheking, and Eloquent model class. Then we wrap
an instance of our provider into Guard class to use advantages such of methods as check(), guest(), user() and so one.

Ok, but where to put all of this code? In app/Providers directory there already exists one service provider for this purpose AuthServiceProvider.
Let’s update it’s boot method with our code:

Then as documentation says we go to our config/auth.php and switch to the new driver:

<?php// ...
'driver'=>'clientEloquent',

But, this will simply replace our admins auth implementation with newly created clients one. So how to fix it?
How to switch programmatically between both?

Use Middleware to Switch Between Drivers

Because we have both admin and client controllers in our application, we need a way to switch between auth drivers. So come
back to config/auth.php file and change driver back to eloquent. This driver will be used by default in admin controllers,
so there is no need to change their code. Our main goal is to add authentication to client controllers.

I’ve chosen to use middleware to change auth driver in client controllers. We call it ClienAuth and place in in app\Http\Middleware
directory:

Finally, we have Profile controller that is available to use the new client auth driver. The same is true about AuthController. Just add this
middleware in the constructor, and AuthenticatesAndRegistersUsers trait will use our new driver to manage users. As you have seen in Laravel 5.1
it is not a trivial task to create separate auth providers in your app.

Laravel 5.2

In Laravel 5.2 multiple authentications are implemented as an inbuilt functionality. Let’s go through the steps to achieve the same results as in
the previous chapter.

Set up models

In order to achieve authentication our Client and Admin models must be instances of Illuminate\Contracts\Auth\Authenticatable:

Change config

Now it’s time to make some changes in config/auth.php. First of all, guards array. This array defines how authentication
is performed for every request. We can either use session or tokens for handling authentication.

In guards array, we are referencing to providers array, which is in the save config file below. providers define which driver
and model class we are going to use for authentication. The driver can be either eloquent or database or any custom driver.
We must change it accordingly:

Then if you want, you can add changes to passwords array. After all, we there is one more change in defaults array. We want Laravel
to use users guard by default.

<?php'defaults'=>['guard'=>'users','passwords'=>'users']

Guard Instance

If we have more than one authentication table, we must use Auth::guard in a different way we did it before. Now we must specify
what guard we want to use (they are listed in config/auth.php file in guards array):