Reference

Laravel Reference

Separate Authentication for Admin and User

Laravel's auth scaffold is great for a site where only users have to log in. But what if you want a separate login for admins, with its own view, its own controller and methods, etc.? One way to do that is to assign user roles and permissions. You could create your own roles and permissions, or you could use a package like Laratrust.

Note: The following assumes you will store all models in the app\Models directory, as on this page. Also, it's assumed that you've been following this tutorial and have already run php artisan make:auth.

Customize auth scaffold for users

Customize Laravel's auth scaffold according to this page.

Install Laratrust

composer require "santigarcor/laratrust:5.2.*"

Note: This is obviously for Laratrust version 5.2. Check the Laratrust documentation for the most recent version.

In your config/app.php add the following to the providers array:

/*
 * Package Service Providers...
 */
Laratrust\LaratrustServiceProvider::class,

In the same config/app.php add the following at the end of the aliases array:

'Laratrust' => Laratrust\LaratrustFacade::class,

Then publish the vendor package:

php artisan vendor:publish --tag="laratrust"

Then run:

php artisan laratrust:setup

If you want to change the default role keys from "superadministrator" to "superadmin" or "administrator" to "admin" you can do this in config/laratrust_seeder.php.

'role_structure' => [
    'superadmin' => [

Then create the seeder:

php artisan laratrust:seeder

Next be sure to change all the model references from App/ to App/Models in the following files:

  • app/Models/Permission.php
  • app/Models/Role.php
  • app/Models/User.php
  • config/auth.php
  • config/laratrust.php
  • database/seeds/LaratrustSeeder.php

And if you've added name_first and name_last columns to your user table and if they require non-NULL values, be sure to add those to database/seeds/LaratrustSeeder.php for creating new users:

$user = \App\Models\User::create([
    'name' => ucwords(str_replace('_', ' ', $key)),
    'name_first' => 'FirstName',
    'name_last' => 'LastName',
    'email' => $key.'@app.com',
    'password' => bcrypt('password')
]);

Be sure to add the seeder to the run() method in database/seeds/DatabaseSeeder.php:

public function run()
    {
        // $this->call(UsersTableSeeder::class);
        $this->call(LaratrustSeeder::class);
    }

Then:

composer dump-autoload

And finally:

php artisan migrate --seed

Create Admin controllers, routes and views

Note: The following needs to be rewritten to use the Laratrust package.

Create separate controller and view directories

Create a new directory at app/Http/Controllers/Admin

Create a new directory at resources/views/admin

Copy controller and view files

Copy /app/Http/Controllers/Auth to /app/Http/Controllers/Admin/Auth

Copy /resources/views/auth to /resources/views/admin/auth

Create dashboard controller and views

Create DashboardController

Copy contents of DashboardController from Account. Be sure to change the namespace.

Change:

$this->middleware('admin.auth');

Change:

return view('admin.dashboard');

Create admin dashboard view:

Copy dashboard view from users/ — change path of layouts master view

Modify the Admin Auth controllers

Change all the namespaces to /app/Http/Controllers/Admin/Auth

ForgotPasswordController

$this->middleware('admin.guest');

LoginController

Add this to the top:

use Illuminate\Http\Request;
use Illuminate\Support\Facades\Auth;

Set the following:

protected $redirectTo = 'admin';

In the constructor:

$this->middleware('admin.guest')->except('logout');

Add showLoginForm():

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

Add logout():

public function logout(Request $request)
{
    $this->guard('admin')->logout();
    $request->session()->flush();
    $request->session()->regenerate();
    return redirect('admin');
}

Add guard():

protected function guard()
{
    return Auth::guard('admin');
}

RegisterController

Add this to the top:

use App\Models\Admin;
use Illuminate\Support\Facades\Auth;

Set the following:

protected $redirectTo = 'admin';

In the constructor:

$this->middleware('admin.guest');

Change fields in #[strong validator()] and #[strong create()] methods as needed.

In validator():

'email' => 'required|string|email|max:255|unique:admins',

Add the following methods:

/* ???? */
return Admin::create()

In create(), change:

'email' => 'required|string|email|max:255|unique:admins',

ResetPasswordController

Set the following:

protected $redirectTo = 'admin';

In the constructor:

$this->middleware('admin.guest');

Add/Change Middleware

CheckIfAdminAuthenticated

Copy the code for this from RedirectIfAuthenticated

Be sure to change the class name to CheckIfAdminAuthenticated

In handle():

$auth = Auth::guard('admins');
if (!$auth->check()) {
    return redirect('admin');
}
return $next($request);

RedirectIfAdminAuthenticated

Copy the code for this from RedirectIfAuthenticated

Be sure to change the class name to RedirectIfAdminAuthenticated

In handle():

if (Auth::guard('admin')->check()) {
    return redirect('admin');
}

RedirectIfAdminNotAuthenticated

Copy the code for this from RedirectIfAuthenticated

Be sure to change the class name to RedirectIfAdminNotAuthenticated

In handle():

if (!Auth::guard('admin')->check()) {
    return redirect('admin');
}

Edit Kernel.php

Add this to the top:

use App\Http\Middleware\RedirectIfAdminAuthenticated;
use App\Http\Middleware\RedirectIfAdminNotAuthenticated;

Add the following to #[strong $routeMiddleware] at the bottom:

'admin.auth' => \App\Http\Middleware\RedirectIfAdminNotAuthenticated::class,
'admin.guest' => \App\Http\Middleware\RedirectIfAdminAuthenticated::class,

Edit Admin.php

Copy everything from User.php

Change class name from User to Admin

Make sure the class is referencing the correct table and $fillable and $hidden fields.

config/auth.php

Add this to the #[strong guards] array:

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

Add this to the #[strong providers] array:

'admins' => [
    'driver' => 'eloquent',
    'model' => App\Models\Admin::class,
],

Add this to the passwords array:

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

Add route group with admin prefix

Route::prefix('admin')->group(function() {
    Route::get('login', 'Admin\Auth\LoginController@showLoginForm');
    Route::get('register', 'Admin\Auth\RegisterController@showRegistrationForm');
    Route::post('login', 'Admin\Auth\LoginController@login')->name('admin.login');
    Route::post('register', 'Admin\Auth\RegisterController@register')->name('admin.register');
    Route::post('password/reset', 'Admin\Auth\ForgotPasswordController@showLinkRequestForm')->name('admin.password.request');

    Route::middleware(['admin.auth'])->group(function() {
        Route::get('/', 'Admin\DashboardController@index');
        Route::post('logout', 'Admin\Auth\LoginController@logout')->name('admin.logout');
        Route::any('{page}', 'Admin\ErrorController@error404')->where('page', '(.*)');
    });
});

Modify views

The rest involves modifying the views in views/admin/auth, including:

  • Making sure the correct master layout is being used
  • Checking that the links are going to the right places
  • Changing instances of @if(Auth::guest()) to @if(Auth::guard('admin')->guest())
  • Changing instances of @if(Auth::check()) to @if(Auth::guard('admin')->check())