After I used the awesome features of authentication guards in Laravel to create multiple user accounts in my application, I thought it wise to put it down for those that might need the knowledge.

In this chapter, I will be covering how to create Admin and Vendor account using Laravel Multi Authentication.

Before proceeding with how to get things done, i strongly recommend to go through documentation of Authentication in Laravel 

Why do we need it

There are instances where we wanted to have a separate authentications logic for administrators apart from default user, some may argue that authorization/roles can accomplish this goal. But there are situations where we want to have different rules and relationships for user and administrator.

Chapter I :: Registration for Admin

Here we will cover registration of our custom users whom we will call ADMIN and VENDOR. We will not be using new features of laravel 5.4 like Markdown Mail & Notifications & Fluent Routing because we want this steps to work in Laravel 5.3 too. So, Let’s dig in.

You can install a fresh copy of Laravel or can use your existing project (must be in v5.4 or higher)

Now let’s run Laravel’s authentication scaffolding

php artisan make:auth

Well you might be wondering, this topic is about MultiAuth,why should we care about laravel’s default user. Well, the idea is to have three users account – Admin, Vendor and Customers. But depending on the needs of your application, you can skip this procecss.

Let’s create new models and migration for our custom users Admin and Vendor.

php artisan make:model Admin -m php artisan make:model Vendor -m

Open up the admin and vendor migration files, and add the necessary columns to the tables.

public function up()     {
        Schema::create('admins', function (Blueprint $table) {
          $table->increments('id');
          $table->string('name');
          $table->string('email')->unique();
          $table->string('password');
          $table->rememberToken();
          $table->timestamps();
        });
    }
 
    public function down()     {
        Schema::dropIfExists('admins');
    }

Do the same for vendors table. Now we can run the migrations, this will create Admins and Vendors tables along with other tables if any.

php artisan migrate

Setting Expectations

Lets begin by adding registration related routes in web routes of our project. Open routes/web.php file and add the below routes for now.

//web.php
//other routes
 
Route::get('admin-register', Auth\AdminAuthController@showLoginForm);
Route::post('admin-register', 'Auth\AdminAuthController@register');

You can replace the URL terms admin-register and vendor-register with names of your choice, but you have to be consistent with the names to avoid confusion.

NB: You might be wondering why I wrote only showLoginForm for AdminController instead of showRegistrationForm, well, it is because the template I am using for Admin dashboard has both registration and login on the same page. And yeah I know there shouldn’t be registration page showing for Admin, I just felt having it showing during development phase will make things easier for me. I will move the registration inside the dashboard later on.

Accomplish the Expectations

Now let’s work on the first two routes Route::get(‘admin-register’, ‘Auth\AdminController @register’); . It says when GET request is made for admin-register page, laravel will call doRegister() method of Auth\AdminController.

Lets create our AdminController and VendorController for admin and vendor

php artisan make:controller Auth/AdminAuthController
php artisan make:controller Auth/VendorAuthController

Lets begin editing our AdminAuth controller (Auth/AdminAuthController) by adding doRegister()

//AdminAuthController.php
 
namespace App\Http\Controllers\Auth;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
 
class AdminAuthController extends Controller {
  //shows registration/login form to admin   public function showLoginForm()   {
      return view('admin.login');
  }
}

Now I am going to assume you are familiar with structuring your views into layout files, if not, well that would be a topic for another day. So I will just go straight to showing the necessary code snippets that we need for registration. Just fill in the blanks on your own.

Here is the necessary code snippets for login.blade.php –

<script> 
 window.Laravel =  echo json_encode([ 
 'csrfToken' => csrf_token(),  ]); 
< script> 

Add the following lines within your body tag for displaying error messages

//for displaying error messages
@if (count($errors))
   @foreach ($errors->all() as $error)
{{ $error }} @endforeach
@endif

The main form for registration

<form method="POST" action="{{ url('/admin-login') }}">
{{ csrf_field() }}
<input type="email" name="email" placeholder="Email" />
<input type="text" name="name" placeholder="Username" />
<input type="password" name="password" placeholder="Password" />
<input type="password" name="password_confirmation" placeholder="Repeat password" />
<input type="submit" value="Register" />

Lets work on the next route Route::post(‘admin-register’, ‘Auth\AdminAuthController@dregister’); where we handle data POST’ed from register view. Let’s create register() method in our AdminAuthController.

    public function register(Request $request)
    {
	//Validates data
        $this->validator($request->all())->validate();
	
	//Create admin
        $admin = $this->create($request->all());
	
	//Authenticates admin
        $this->guard()->login($admin);
	
	//Redirects admin
        return redirect($this->redirectTo);
    }

   protected function validator(array $data)
    {
        return Validator::make($data, [
            'name' => 'required|max:255',
            'email' => 'required|email|max:255|unique:users',
            'password' => 'required|min:6|confirmed',
        ]);
    }

     //Create a new admin instance after a validation.
    protected function create(array $data)
    {
        return Admin::create([
            'name' => $data['name'],
            'email' => $data['email'],
            'password' => bcrypt($data['password']),
        ]);
    }

//Get the guard to authenticate User
   protected function guard()
   {
       return Auth::guard('admin');
   }

Ok, I know what you might me thinking, what is Auth::guard(‘admin’), the Auth::guard() method is used by laravel for authentication, this returns default guard which can authenticate users. But we want to authenticate admins, so we have  totell laravel to authenticate our admins with our custom guard ‘admin’.

So, let us now create our custom guard ‘admin’, let’s begin with adding new User Provider for our custom guard. The user provider tells laravel about the model/table it has to refer for custom guard.

To do this open the config/auth.php file and add new user provider admin to providers array.

//auth.php     
'providers' => [
        'users' => [            
'driver' =>
'eloquent',
           
'model' => App\User::class,
        ],
 
       //Admin user provider
       
'admins' => [
            
'driver' =>
'eloquent'//We are using eloquent model
           
'model' => App\Admin::class,
       
],
    ],

Now let’s create our new custom guard in the guards array of the same page config/auth.php. We need to specify the guard driver and user provider for our guard. We will be using session as guard driver (This tutorial is about session based login) and admin as user provider which we have already defined.

//auth.php
 
'guards' => [
       
'web' => [
           
'driver' =>
'session',
            
'provider' =>
'users',
        ],
 
     
//Our new custom driver.

        'admin' => [            
'driver' => 'session',
           
'provider' =>
'admins',
        ], ],

Our custom guard is ready to be used by laravel for authenticating admins. The last step taken by our register() method in AdminAuthController is redirecting admin to a page when login is successful.

So, let’s declare the redirectPath property for the admin in AdminAuthController , this will redirect admin to the dashboard page.

//AdminAuthController.phpnamespace App\Http\Controllers\Auth;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Auth;
//Validator facade used in validator method
use Illuminate\Support\Facades\Validator;
//Admin Model
use App\Admin;
//Class needed for login and Logout logic
use Illuminate\Foundation\Auth\AuthenticatesUsers;

class AdminAuthController extends Controller
{
use AuthenticatesUsers;

/**
* Where to redirect users after login.
*
* @var string
*/
protected $redirectTo = 'admin';

public function register(Request $request)
{

//Validates data
$this->validator($request->all())->validate();

//Create admin
$admin = $this->create($request->all());

//Authenticates admin
$this->guard()->login($admin);

//Redirects admins
return redirect($this->redirectTo);
}

protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:admins',
'password' => 'required|min:6|confirmed',
]);
}

//Create a new admin instance after a validation.
protected function create(array $data)
{
return Admin::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}

//Shows admin login form
public function showLoginForm()
{
return view(admin.login');
}

//Get the guard to authenticate User
protected function guard()
{
return Auth::guard('admin');
}
}
We need to extend Illuminate\Foundation\Auth\User class in our Admin Model. This class implements Illuminate\Contracts\ Auth\Authenticatable interface and has declared all the necessary methods.

So let’s extend Illuminate\Foundation\Auth\User class and add mass assignable & hidden attributes in our Admin Model (app/Admin.php).

namespace App;

use Illuminate\Database\Eloquent\Model;
//Class which implements Illuminate\Contracts\Auth\Authenticatable
use Illuminate\Foundation\Auth\User as Authenticatable;

class Admin extends Authenticatable
{
//Mass assignable attributes
protected $fillable = [
'name', 'email', 'password',
];

//hidden attributes
protected $hidden = [
'password', 'remember_token',
];

}

End of chapter