Multiple authentication in Laravel 5.2

 

Multiple authentication in laraval has been a developer’s cry for a long time and now it has finally reached Taylor Otwell to feature it as inbuilt functionality in Laravel 5.2.  While working on one of my client project, I came across this feature in Laravel 5.2 and thought to write a blog on it. Let’s get started

Multiple authentication in Laravel 5.2

    Setting up tables
    Generating models
    Configuring auth.php
    Authentication
    Guard Instance


1. Setting up tables

In this example, we are going to handle two authentication system.

    User
    Admin

Start by creating migration files for them. By default, laravel ships with user table migration file. So we will create migration file for admin alone
$ php artisan make:migration create_admins_table

   
$ php artisan make:migration create_admins_table

Admin Migration File
<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateAdminsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('admins', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->string('password', 60);
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('users');
    }
}

   
<?php

use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;

class CreateAdminsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('admins', function (Blueprint $table) {
            $table->increments('id');
            $table->string('name');
            $table->string('email')->unique();
            $table->string('password', 60);
            $table->rememberToken();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::drop('users');
    }
}



Once migration files are set, let’s migrate it.
$ php artisan migrate

   
$ php artisan migrate


2. Generating models

Now that we have two tables, let’s create model files. Again by default, laravel ships with User model file. We will only have to create model for Admin
$ php artisan make:model Admin
1   
$ php artisan make:model Admin

Admin Model
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Admin extends Model
{
    //
}

   
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Admin extends Model
{
    //
}

Now if you open up Admin model file you will notice that it extends Model class. In order to achieve authentication with Admin model we need to replace Model class with Authenticatable class. Also add the necessary variables such as fillable and hidden.

    Note : Without extending Authenticatable class for model will throw you Argument 1 passed to Illuminate\Auth\EloquentUserProvider::validateCredentials() must be an instance of Illuminate\Contracts\Auth\Authenticatable Exception

<?php

namespace App;

use Illuminate\Foundation\Auth\User as Authenticatable;

class Admin extends Authenticatable
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];
}

   
<?php

namespace App;

use Illuminate\Foundation\Auth\User as Authenticatable;

class Admin extends Authenticatable
{
    /**
     * The attributes that are mass assignable.
     *
     * @var array
     */
    protected $fillable = [
        'name', 'email', 'password',
    ];

    /**
     * The attributes excluded from the model's JSON form.
     *
     * @var array
     */
    protected $hidden = [
        'password', 'remember_token',
    ];
}

Great! Now we have tables and model files set. Lets move to configuring auth.php file
Configuring auth.php

Open your auth.php file inside app/config folder.
<?php

return [

    'defaults' => [
        'guard'     => 'web',
        'passwords' => 'users',
    ],

    'guards' => [
        'web' => [
            'driver'   => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver'   => 'token',
            'provider' => 'users',
        ],
    ],

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\User::class,
        ],
    ],

    'passwords' => [
        'users' => [
            'provider' => 'users',
            'email' => 'auth.emails.password',
            'table' => 'password_resets',
            'expire' => 60,
        ],

    ],

];

   
<?php

return [

    'defaults' => [
        'guard'     => 'web',
        'passwords' => 'users',
    ],

    'guards' => [
        'web' => [
            'driver'   => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver'   => 'token',
            'provider' => 'users',
        ],
    ],

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\User::class,
        ],
    ],

    'passwords' => [
        'users' => [
            'provider' => 'users',
            'email' => 'auth.emails.password',
            'table' => 'password_resets',
            'expire' => 60,
        ],

    ],

];

You will notice an array with set of values. Lets see one by one.

defaults – By default, laravel is going to handle authentication system for User model by using web guard.

guards – guard define how authentication is performed for every request. We can either use session or tokens for handling authentication. Inside guards, you might find web array. Web array explains how user is authenticated every request (via sessions). Also, it uses a provider called users for authentication.

providers – providers explains us which driver and model file we are going to use for authentication. Here we see eloquent driver and User model class. Driver can be either eloquent or database or any custom driver.

passwords – password fields explains about how password reset is handled. For users guard, it is going to use users provider, and password_resets table.

Now that we have seen how this works, lets tweak the auth config file to support authentication for admin
<?php

return [

    'defaults' => [
        'guard'     => 'web',
        'passwords' => 'users',
    ],

    'guards' => [
        'web' => [
            'driver'   => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver'   => 'token',
            'provider' => 'users',
        ],
       
        // For admin
        'admins' => [
            'driver'   => 'session',
            'provider' => 'admins'
        ]
    ],

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\User::class,
        ],
       
        // For admin
        'admins' => [
            'driver' => 'eloquent',
            'model' => App\Admin::class
        ]
    ],

    'passwords' => [
        'users' => [
            'provider' => 'users',
            'email' => 'auth.emails.password',
            'table' => 'password_resets',
            'expire' => 60,
        ],
        'admins' => [
            'provider' => 'admins',
            'email' => 'auth.emails.password',
            'table' => 'password_resets',
            'expire' => 60,
        ],
    ],

];

   
<?php

return [

    'defaults' => [
        'guard'     => 'web',
        'passwords' => 'users',
    ],

    'guards' => [
        'web' => [
            'driver'   => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver'   => 'token',
            'provider' => 'users',
        ],
       
        // For admin
        'admins' => [
            'driver'   => 'session',
            'provider' => 'admins'
        ]
    ],

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\User::class,
        ],
       
        // For admin
        'admins' => [
            'driver' => 'eloquent',
            'model' => App\Admin::class
        ]
    ],

    'passwords' => [
        'users' => [
            'provider' => 'users',
            'email' => 'auth.emails.password',
            'table' => 'password_resets',
            'expire' => 60,
        ],
        'admins' => [
            'provider' => 'admins',
            'email' => 'auth.emails.password',
            'table' => 'password_resets',
            'expire' => 60,
        ],
    ],

];

Perfect! Now our auth file is ready to be tested. But before checking, we need to do an important task. Adding $guard to Admin model.
protected $guard = "admins";

   
protected $guard = "admins";

Add the above line to Admin model file.
Authentication

First, lets use laravel’s default boilerplate template for authentication
$ php artisan make:auth

   
$ php artisan make:auth

Above line will add necessary views and controllers for authentication. Note that in routes.php file you might see your authentication routes wrapped within a middleware group called web. If you open up your kernel.php file within app folder you might see it uses session classes. So in Laravel 5.2 to maintain the user session all your routes should be wrapped within this middleware group. Now try logging in as user.

    Note : As soon as you try login as either user or admin, you will be redirected to home where you might still see the login/register links in menu which are not supposed to be seen after successfull login. The reason behind it is because Route::get('/') isn’t under middleware group web if you inspect in routes.php file. Move it under web middleware group and it will work. As mentioned above, sessions will work only within this group.

Now try changing defaults in auth.php file to something like this
'defaults' => [
    'guard'     => 'web',
    'passwords' => 'users',
],

   
'defaults' => [
    'guard'     => 'web',
    'passwords' => 'users',
],

This will make admin as default login in system.
Guard Instance

In order to perform authentication you need to get hold of guard instance which can be done by following code
// By using auth helper function

auth()->guard('admins')->attempt(['email' => '', 'password' => ''])

// or using Facade

Auth::guard('admins')->attempt(['email' => '', 'password' => ''])

// To get authenticated admin

auth()->guard('admins')->user()

// To check whether admin is logged in or not

auth()->guard('admins')->check()

   
// By using auth helper function

auth()->guard('admins')->attempt(['email' => '', 'password' => ''])

// or using Facade

Auth::guard('admins')->attempt(['email' => '', 'password' => ''])

// To get authenticated admin

auth()->guard('admins')->user()

// To check whether admin is logged in or not

auth()->guard('admins')->check()

Thats it! Now you can perform multiple authentication in laravel 5.2 with ease. See you in another interesting tutorial!
Powered by Blogger.