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())