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.
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
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?
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
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
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
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:
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
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
Register ClientAuth middleware in
Kernel.php as routeMiddleware:
Enable middleware in controller:
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.
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
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.
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
users guard by default.
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
guard we want to use (they are listed in
config/auth.php file in
AuthController to change guard instance simply define a
If you want you can implement special middlewares for your guards and then use them in controllers. For example:
Register middlware in
Use middleware in for example ProfileController:
And it’s done! As you have seen it’s much easier that it was in Laravel 5.1, were we had to write too much code, to implement the same things.