How to create a multiple Authentication in Laravel - User Authentication and Admin Authentication

Question:

How to create a multiple Authentication in Laravel - User Authentication and Admin Authentication?

Solution:

Today I'll describe how to create a Multiple Authentication in Laravel 5.5 or below.

Download Full Source Code of Laravel Multi Authentication Demo

 [Adf.ly add -> Wait 5 seconds and click skip ad and download the full codes]


Let's start to our code.


Create Laravel Project. Select htdocs and press ctrl + shift then open command terminal-
composer global require "laravel/installer" 

Then
 laravel new LaraMultiAuthenticationDemo 

It takes upto 5 or 10 minutes depending on your internet speed. Give that time to install the latest version of Laravel. -> Application ready!

Go that folder and run the run command
 php artisan serve 

Like that in command-

That's ok, see the effect in browser. Go to http://localhost:8000


We've completely created our Laravel Project.

Setup the Databases-
Create a database called LaravelMultiAuthenticationDemo and setup in env file.
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=LaravelMultiAuthenticationDemo
DB_USERNAME=root
DB_PASSWORD= 

Create User Authentication-
 run make:auth command to use Laravel's Default Authentication. This is for user and we also create another for admin. First Create for User's Authentication.
 php artisan make:auth 




Change the Website Root Home page-
Go to resources/view/welcome.blade.php  and see there's some basic code is done by Laravel and changed that code with Simple Navigation bar of Bootstrap.
Just insert the css/app.css and js/app.js in the welcome.blade.php and the welcome.blade.php code is-

Welcome.blade.php


<!doctype html>
<html lang="{{ app()->getLocale() }}">
<head>
    <meta charset="utf-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1">

    <title>Laravel Mutli Authentication Demo </title>

    <link href="https://fonts.googleapis.com/css?family=Raleway:100,600" rel="stylesheet" type="text/css">

    <link rel="stylesheet" href="{{ asset('css/app.css') }}">
    <script type="text/javascript" src="{{ asset('js/app.js') }}"></script>

</head>
<body>

    <nav class="navbar navbar-default">
      <div class="container">
        <div class="navbar-header">
          <button type="button" class="navbar-toggle collapsed" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1" aria-expanded="false">
            <span class="sr-only">Toggle navigation</span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
            <span class="icon-bar"></span>
        </button>
        <a class="navbar-brand" href="#">#</a>
    </div>

    <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
      <ul class="nav navbar-nav">
        <li class="active"><a href="#">Home <span class="sr-only">(current)</span></a></li>
        <li><a href="#">Test Link</a></li>
    </ul>
    <ul class="nav navbar-nav navbar-right">

       @auth
       <li><a href="{{ url('/home') }}">User Dashboard</a></li>
       @else
       <li><a href="{{ route('login') }}">Login</a></li>
       <li><a href="{{ route('register') }}">Register</a></li>
       @endauth

   </ul>
</div>
</div><!-- End Container inside nav -->
</nav> <!-- End nav -->


<div class="content">
    <div class="container modal-content modal-dialog">
        <h3>This is our Website Home Page</h3>
    </div>
</div>

</body>
</html>

Ok Let's see the simple output of that code in browser-



Now we need to migrate but theres a work need in app/providers/AppServiceProvider.php,
add Schema class and then in boot function add maximum key length 191 for string remove the old codes and replace the following-
<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;
use Illuminate\Support\Facades\Schema;

class AppServiceProvider extends ServiceProvider
{

    public function boot()
    {
        Schema::defaultStringLength(191);
    }


    public function register()
    {
        
    }
}

Ok, now we run migrate command to migrate the create_users_table in app/database/migrations
 php artisan migrate 

Now look at the localhost and the database table users has created and this is just simple-


Our User Authentication work is complete, Now test the User Authentication Using Registration and Login.

Before registration run php artisan serve command again and refresh browser.

User Registration Page-



Then After Clicking Registration, You are now registered to a User and View will Like this-



So, Laravel User Authentication is successfully Comepleted And we can now Register as a user, Login a a user and also can logout as a user. This user Authentication is total gift of Laravel. The most easiest job.


Next - Admin Authentication

We've Completed our User Authentication and it is time to start for Multiple Authentication or Admin Authentication.

Now look at the routes.php and in Laravel version 5.4 to up there is a routes/web.php and there is only two functions, like:

Auth::routes();

Route::get('/home', 'HomeController@index')->name('home');

Then, make some routes for our Admin And Write the full code inside routes/web.php

Full web.php or routes.php Code:


<?php

/*
|--------------------------------------------------------------------------
| Web Routes
|--------------------------------------------------------------------------
|
| Here is where you can register web routes for your application. These
| routes are loaded by the RouteServiceProvider within a group which
| contains the "web" middleware group. Now create something great!
|
*/

Route::get('/', function (){
 return view('welcome');
});

Auth::routes();

Route::get('/home', 'HomeController@index')->name('/home');
Route::post('/users/logout', 'Auth\LoginController@userLogout')->name('user.logout');

Route::group(['prefix' => 'admin'], function() {
 Route::get('/login', 'Auth\AdminLoginController@showLoginForm')->name('admin.login');
 Route::post('/login', 'Auth\AdminLoginController@login')->name('admin.login.submit');
 Route::post('/logout', 'Auth\AdminLoginController@logout')->name('admin.logout');

 //Password resets routes

 Route::post('/password/email', 'Auth\AdminForgotPasswordController@sendResetLinkEmail')->name('admin.password.email');
 Route::get('/password/reset', 'Auth\AdminForgotPasswordController@showLinkRequestForm')->name('admin.password.request');
 Route::post('/password/reset', 'Auth\AdminResetPasswordController@reset');
 Route::post('/password/reset/{token}', 'Auth\AdminResetPasswordController@showResetForm')->name('admin.password.reset');


 Route::get('/', "AdminController@index")->name('admin.dashboard');
});



We'll talk one by one about them, just don't worry.
Here,

Route::group(['prefix' => 'admin'], function() {
means, we will make all of the admin/ url inside this thus there is no need to write those admin text every time in the url.
Now, create admin migrations for Admin Table -

php artisan make:model Admin --migration

Ok, Admin Table has created successfully. Go to database/migrations/xxxxxxx_create_admin_tables.php, then the admin tables fields code like-

Full create_admins_table.php Code:

<?php

use Illuminate\Support\Facades\Schema;
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('admin_role');
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
        });
    }

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

So, here just make an admin table simply giving name, email, admin_role and password field. Others rememberToken and timestamps are also created for better coding in Laravel.
Then in app/Admin.php or our admin model code will be,

Full app/Admin.php Code:

<?php

namespace App;

use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
use App\Notifications\AdminResetPasswordNotification;

class Admin extends Authenticatable
{
    use Notifiable;
    
    protected $guard = "admin";


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

    /**
     * The attributes that should be hidden for arrays.
     *
     * @var array
     */
    protected $hidden = [
    'password', 'remember_token',
    ];

    /**
     * Send the password reset notification.
     *
     * @param  string  $token
     * @return void
     */
    public function sendPasswordResetNotification($token)
    {
        $this->notify(new AdminResetPasswordNotification($token));
    }
}

Now, look, we've used a varible called guard assigning value = admin. In this line,

    protected $guard = "admin";

So, now setup the guard for our admin and users individually. First Go to config/app.php There is a only guard for our users. Now remove that codes and replace our codes for users and admins both.

Full config/auth.php Code: [without deleting the comment]

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Authentication Defaults
    |--------------------------------------------------------------------------
    |
    | This option controls the default authentication "guard" and password
    | reset options for your application. You may change these defaults
    | as required, but they're a perfect start for most applications.
    |
    */

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

    /*
    |--------------------------------------------------------------------------
    | Authentication Guards
    |--------------------------------------------------------------------------
    |
    | Next, you may define every authentication guard for your application.
    | Of course, a great default configuration has been defined for you
    | here which uses session storage and the Eloquent user provider.
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | Supported: "session", "token"
    |
    */

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

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

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

        'admin-api' => [
            'driver' => 'token',
            'provider' => 'admins',
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | User Providers
    |--------------------------------------------------------------------------
    |
    | All authentication drivers have a user provider. This defines how the
    | users are actually retrieved out of your database or other storage
    | mechanisms used by this application to persist your user's data.
    |
    | If you have multiple user tables or models you may configure multiple
    | sources which represent each model / table. These sources may then
    | be assigned to any extra authentication guards you have defined.
    |
    | Supported: "database", "eloquent"
    |
    */

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

        // 'users' => [
        //     'driver' => 'database',
        //     'table' => 'users',
        // ],
    ],

    /*
    |--------------------------------------------------------------------------
    | Resetting Passwords
    |--------------------------------------------------------------------------
    |
    | You may specify multiple password reset configurations if you have more
    | than one user table or model in the application and you want to have
    | separate password reset settings based on the specific user types.
    |
    | The expire time is the number of minutes that the reset token should be
    | considered valid. This security feature keeps tokens short-lived so
    | they have less time to be guessed. You may change this as needed.
    |
    */

    'passwords' => [
        'users' => [
            'provider' => 'users',
            'table' => 'password_resets',
            'expire' => 60,
        ],

        'admins' => [
            'provider' => 'admins',
            'table' => 'password_resets',
            'expire' => 15,
        ],
    ],

];


So, we've created admins guard, admins provider. Finally set expire = 15 for security reason, thus every 15 minutes after password reset token will be invalid.

Now set the authentication redirect method for admin and for users. Go to app\http\RedirectIfAuthenticated and look the code first and see there is redirect method only for users not for admin.

Full app\http\RedirectIfAuthenticated Code:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Support\Facades\Auth;

class RedirectIfAuthenticated
{
    /**
     * Handle an incoming request.
     *
     * @param  \Illuminate\Http\Request  $request
     * @param  \Closure  $next
     * @param  string|null  $guard
     * @return mixed
     */
    public function handle($request, Closure $next, $guard = null)
    {

        switch ($guard) {
            case 'admin':
            if (Auth::guard($guard)->check()) {
                return redirect()->route('admin.dashboard');
            }
            break;
            
            default:
            if (Auth::guard($guard)->check()) {
                return redirect()->route('/home');
            }
            break;
        }

        return $next($request);
    }
}


Look, we've just added a switch case and if case = admin then check if guard admin is checked or not. If admin guard is checked then redirect to admin dashboard. In this code,
case 'admin':
            if (Auth::guard($guard)->check()) {
                return redirect()->route('admin.dashboard');
            }


Now make a controller called AdminController

php artisan make:controller AdminController


Now, go to app/controller/AdminController.php and change the code to this-

Full app/controller/AdminController.php Code:

<?php
namespace App\Http\Controllers;

use Illuminate\Http\Request;

class AdminController extends Controller
{
    /**
     * Create a new controller instance.
     *
     * @return void
     */
    public function __construct()
    {
        $this->middleware('auth:admin');
    }

    /**
     * Show the application dashboard.
     *
     * @return \Illuminate\Http\Response
     */
    public function index()
    {
        return view('admin');
    }
}


Here, add the middleware in construct, thus everytime this Controller's function is called, this must have to pass the admin guard.
public function __construct()
    {
        $this->middleware('auth:admin');
    }


And in index() function make the view for admin home page. So, let's create the admin.blade.php file for the admin Homepage

admin.php File



@extends('layouts.app')
@section('login_status')
<!-- Authentication Links -->
@if (Auth::guest())
<li><a href="{{ route('admin.login') }}">Login</a></li>
@else
<li class="dropdown">
    <a href="#" class="dropdown-toggle" data-toggle="dropdown" role="button" aria-expanded="false">
        {{ Auth::user()->name }} <span class="caret"></span>
    </a>

    <ul class="dropdown-menu" role="menu">
        <li>
            <a href="{{ route('admin.logout') }}"
            onclick="event.preventDefault();
            document.getElementById('logout-form').submit();">
            Logout
        </a>

        <form id="logout-form" action="{{ route('admin.logout') }}" method="POST" style="display: none;">
            {{ csrf_field() }}
        </form>
    </li>
</ul>
</li>
@endif
@endsection
@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <div class="panel panel-primary">
                <div class="panel-heading">Admin Dashboard</div>
            </div>
        </div>
    </div>
</div>
@endsection


Also create admin-login.php in resources/views/auth folder

admin-login.php File



@extends('layouts.app')

@section('content')
<div class="container">
    <div class="row">
        <div class="col-md-8 col-md-offset-2">
            <div class="panel panel-default">
                <div class="panel-heading">Admin Login</div>
                <div class="panel-body">
                    <form class="form-horizontal" method="POST" action="{{ route('admin.login.submit') }}">
                        {{ csrf_field() }}

                        <div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
                            <label for="email" class="col-md-4 control-label">E-Mail Address</label>

                            <div class="col-md-6">
                                <input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" required autofocus>

                                @if ($errors->has('email'))
                                    <span class="help-block">
                                        <strong>{{ $errors->first('email') }}</strong>
                                    </span>
                                @endif
                            </div>
                        </div>

                        <div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
                            <label for="password" class="col-md-4 control-label">Password</label>

                            <div class="col-md-6">
                                <input id="password" type="password" class="form-control" name="password" required>

                                @if ($errors->has('password'))
                                    <span class="help-block">
                                        <strong>{{ $errors->first('password') }}</strong>
                                    </span>
                                @endif
                            </div>
                        </div>

                        <div class="form-group">
                            <div class="col-md-6 col-md-offset-4">
                                <div class="checkbox">
                                    <label>
                                        <input type="checkbox" name="remember" {{ old('remember') ? 'checked' : '' }}> Remember Me
                                    </label>
                                </div>
                            </div>
                        </div>

                        <div class="form-group">
                            <div class="col-md-8 col-md-offset-4">
                                <button type="submit" class="btn btn-primary">
                                    Login
                                </button>

                                <a class="btn btn-link" href="{{ route('admin.password.request') }}">
                                    Forgot Your Password?
                                </a>
                            </div>
                        </div>
                    </form>
                </div>
            </div>
        </div>
    </div>
</div>
@endsection


So, our login-view has completed. Let's make the important AdminLoginController in app/http/controllers/auth/ folder

Full AdminLoginController

Create AdminLoginController first using Artisan Command : php artisan make:controller AdminLoginController, then the code in AdminLoginController is -
<?php

namespace App\Http\Controllers\Auth;

use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Auth;

class AdminLoginController extends Controller
{

    protected $redirectTo = '/admin';

 public function __construct(){
  $this->middleware('guest:admin', ['except' => ['logout']]);
 }


    public function showLoginForm(){
     return view('auth.admin-login');
    }

    public function login(Request $request){
     
     //Validate the form data
     $this->validate($request, [
      'email'   => 'email|required',
      'password'   => 'required|min:6'
      ]);

     //Attempt to log the user in
     if (Auth::guard('admin')->attempt(['email' => $request->email, 'password' => $request->password], $request->remember)) {
      //If successful then redirect to the intended location
      return redirect()->intended(route('admin.dashboard'));
      
     }

     //If unsuccessfull, then redirect to the admin login with the data
     return redirect()->back()->withInput($request->only('email', 'remember'));
    }


    public function logout()
    {
        Auth::guard('admin')->logout();
        return redirect()->route('admin.login');
    }
}



Now modify the Exception handler unauthenticated function inside app/Exceptions/handler.php

protected function unauthenticated($request, AuthenticationException $exception)
    {
        if ($request->expectsJson()) {
            return response()->json(['error' => 'Unauthenticated.'], 401);
        }

        $guard = array_get($exception->guards(), 0);

        switch ($guard) {
            case 'admin':
                $login = 'admin.login';
                break;
            
            default:
                $login = 'login';
                break;
        }
        return redirect()->guest(route($login));
    }


Ok, now your 90% Work for Admin Authentication is complete,

Run
php artisan migrate
command and migrate the admins_table.

Now create an admin using artisan tinker command;

F:\xampp\htdocs\LaraMultiAuthenticationDemo>php artisan tinker
Psy Shell v0.8.11 (PHP 7.1.7 — cli) by Justin Hilemanan
>>> $admin = new App\Admin
=> App\Admin {#752}
>>> $admin->name = "Admin"
=> "Admin"
>>> $admin->email = "admin@test.com"
=> "admin@test.com"
>>> $admin->password = Hash::make('12345678')
=> "$2y$10$Dv.RAyWlp.GAHNJj.WjXEei0.W.RuBgxyvVF2wF3GucKsl738Hm2q"
>>> $admin->admin_role = "Super Admin"
=> "Super Admin"
>>> $admin->save();

Output and exact code/result of that tinker command is just like-

How to create a multiple Authentication in Laravel - User Authentication and Admin Authentication


So, we can now log in in Admin with the
email = admin@test.com and
password = 12345678.

Ok, check the code in Live; go to localhost:8000/admin/login, the page is look like,

How to create a multiple Authentication in Laravel - User Authentication and Admin Authentication

After clicking on Login, the page will go to the Admin Home page which is look like,

How to create a multiple Authentication in Laravel - User Authentication and Admin Authentication


So, we can now successfully set the Admin Panel Login, Logout and User's Login, Register, Logout successfully.

[Thanks for your patients. Stay with us to get the admin forget password + email reset link validation]

Download Full Source Code of Laravel Multi Authentication Demo

 [Adf.ly add -> Wait 5 seconds and click skip ad and download the full codes]

Note: The database file is given inside the project. Import that sql file for your work and named the database by the above name LaravelMultiAuthenticationDemo.


Having any problems to understand the Laravel Multi Authentication Demo Project, just comment out below.


Tags:
Laravel Authentication, Laravel basic Authentication, Laravel Authentication, Laravel Multiple Authentication, Laravel Auth generate, Laravel Auth,

How to create a multiple Authentication in Laravel - User Authentication and Admin Authentication How to create a multiple Authentication in Laravel - User Authentication and Admin Authentication Reviewed by Maniruzzaman Akash on October 06, 2017 Rating: 5

5 comments:

  1. Excellent tutorial.

    waiting for your next article.
    please quickly upload [admin forget password + email reset link validation] this tutorial

    ReplyDelete
  2. Hey Nice Blog!! Thanks For Sharing!!!Wonderful blog & good post.Its really helpful for me, waiting for a more new post. Keep Blogging!
    best java training in coimbatore
    php training in coimbatore
    best php training institutes in coimbatore

    ReplyDelete

Powered by Blogger.