Laravel provide authentication out of the box with many features and perks, in this tutorial we'll use it to implement multiple authentication system meaning having different type of users let's say admin or author.
What drove me to this approach is the attempt to extended laravel authentication to support multi auth without losing any functionality.
Blog will be the tutorial subject where we implement admin auth alongside the default user auth.
Content:
- Initialization
- Model and Migration
- Configuration
- Service Provider
- Middlewares
- Controllers
- Routing
- Views
- Conclusion
Create a fresh laravel installation with authentication scaffolding included and configure Database and Mail in .env
laravel new blog --auth
Setup Password Confirmation
routes/web.php
-
copy documentation demo route and register it as '/confirmed' and make it return 'password confirmed' string
Route::get('/confirmed', function () { return 'password confirmed'; })->middleware(['auth', 'password.confirm']);
Setup Email Verification
app/User.php
- in
App\Usermodel implementIlluminate\Contracts\Auth\MustVerifyEmail
routes/web.php
-
email verification routes are disabled by default we'll have to enable them, in
Auth::routesmethod set the verify option to trueAuth::routes(['verify' => true]);
-
copy documentation demo route and register it as '/verified' and make it return 'email verified' string
Route::get('/verified', function () { return 'email verified'; })->middleware('verified');
Setup API Authentication
Note: this feature completes laravel authentication by providing simple api authentication which we think is missing but is actually there, it's available since 5.2 release but without documentation it was just mentioned in the authentication documentation, in 5.8 release luckily they decided to document it, in 7.x release for some reason the documentation is gone although the feature still exists (probably it has something to do with releasing Sanctum Package that offers similar capabilities).
database/migrations/xxxx_xx_xx_xxxxxx_create_users_table.php
-
api authentication uses the token driver which require a column to store tokens by default this column is named api_token, in users migration add api_token column
Schema::create('users', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); $table->string('api_token', 80)->unique()->nullable()->default(null); $table->rememberToken(); $table->timestamps(); });
app/Http/Controllers/Auth/RegisterController.php
-
in
createmethod assign random api token to user during registrationuse Illuminate\Support\Str; protected function create(array $data) { return User::create([ 'name' => $data['name'], 'email' => $data['email'], 'password' => Hash::make($data['password']), 'api_token' => Str::random(80), ]); }
app/User.php
-
because user registration logic use mass assignment the previous step won't work unless we make api_token attribute mass assignable by adding it to
$fillablepropertyprotected $fillable = [ 'name', 'email', 'password', 'api_token' ];
Create admin model and it's corresponding migration
php artisan make:model -m Admin
database/migrations/xxxx_xx_xx_xxxxxx_create_admins_table.php
-
we'll use user migration as a template for admin migration, copy user migration columns into admin migration
Schema::create('admins', function (Blueprint $table) { $table->id(); $table->string('name'); $table->string('email')->unique(); $table->timestamp('email_verified_at')->nullable(); $table->string('password'); $table->string('api_token', 80)->unique()->nullable()->default(null); $table->rememberToken(); $table->timestamps(); });
app/Admin.php
-
we'll use user model as a template for admin model, replace admin model code with user model code and change the class name accordingly
<?php namespace App; use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Foundation\Auth\User as Authenticatable; use Illuminate\Notifications\Notifiable; class Admin extends Authenticatable implements MustVerifyEmail { use Notifiable; /** * The attributes that are mass assignable. * * @var array */ protected $fillable = [ 'name', 'email', 'password', 'api_token' ]; /** * The attributes that should be hidden for arrays. * * @var array */ protected $hidden = [ 'password', 'remember_token', ]; /** * The attributes that should be cast to native types. * * @var array */ protected $casts = [ 'email_verified_at' => 'datetime', ]; }
Admin model extends Authenticatable an alias for Illuminate\Foundation\Auth\User which provide authentication functionalities, the latter use Illuminate\Auth\Passwords\CanResetPassword trait to include reset password necessary methods, this trait use ResetPasswordNotification an alias for Illuminate\Auth\Notifications\ResetPassword notification to send reset password email containing reset password link that expire after a period specified in user reset password configuration, we'll customize this notification to receive reset password url and configuration as parameters.
Create a new notification named ResetPasswordNotification
php artisan make:notification ResetPasswordNotification
app/Notifications/ResetPasswordNotification.php
-
import and extend
Illuminate\Auth\Notifications\ResetPassword -
remove
Illuminate\Bus\Queueable,Illuminate\Contracts\Queue\ShouldQueue,Illuminate\Notifications\Notificationimports -
remove
Queueabletrait -
remove
via,toMail,toArraymethods -
define
$resetPasswordRoute,$resetPasswordConfigpropertiesclass ResetPasswordNotification extends ResetPassword { public $resetPasswordRoute; public $resetPasswordConfig; // ... }
-
in constructor define
$tokenparent class property and nullable$resetPasswordRoute,$resetPasswordConfigparameters, call parent constructor, assign$resetPasswordRoute,$resetPasswordConfigparameters to corresponding propertiespublic function __construct($token, $resetPasswordRoute = null, $resetPasswordConfig = null) { parent::__construct($token); $this->resetPasswordRoute = $resetPasswordRoute; $this->resetPasswordConfig = $resetPasswordConfig; }
-
override
Illuminate\Auth\NotificationsResetPasswordnotification toMail method using same code, use$resetPasswordRouteproperty instead of 'password.reset' and$resetPasswordConfigproperty instead ofconfig('auth.defaults.passwords')when properties are not null, importIlluminate\Support\Facades\Languse Illuminate\Support\Facades\Lang; public function toMail($notifiable) { if (static::$toMailCallback) { return call_user_func(static::$toMailCallback, $notifiable, $this->token); } if (static::$createUrlCallback) { $url = call_user_func(static::$createUrlCallback, $notifiable, $this->token); } else { $url = url(config('app.url').route($this->resetPasswordRoute ?: 'password.reset', [ 'token' => $this->token, 'email' => $notifiable->getEmailForPasswordReset(), ], false)); } return (new MailMessage) ->subject(Lang::get('Reset Password Notification')) ->line(Lang::get('You are receiving this email because we received a password reset request for your account.')) ->action(Lang::get('Reset Password'), $url) ->line(Lang::get('This password reset link will expire in :count minutes.', ['count' => config('auth.passwords.'.($this->resetPasswordConfig ?: config('auth.defaults.passwords')).'.expire')])) ->line(Lang::get('If you did not request a password reset, no further action is required.')); }
app/Admin.php
-
override
Illuminate\Auth\Passwords\CanResetPasswordtrait sendPasswordResetNotification method using same code, inResetPasswordNotificationinstantiation pass$resetPasswordRouteparameter as 'admin.password.reset' and$resetPasswordConfigparameter as 'admins' alongside$token, importApp\Notifications\ResetPasswordNotificationuse App\Notifications\ResetPasswordNotification; public function sendPasswordResetNotification($token) { $this->notify(new ResetPasswordNotification($token, 'admin.password.reset', 'admins')); }
Admin model extends Authenticatable an alias for Illuminate\Foundation\Auth\User which provide authentication functionalities, the latter use Illuminate\Auth\MustVerifyEmail trait to include email verification necessary methods, this trait use Illuminate\Auth\Notifications\VerifyEmail notification to send emails containing verification link, we'll customize this notification to receive email verification route as parameter instead of using staticly defined one.
create a new notification named VerifyEmailNotification
php artisan make:notification VerifyEmailNotification
app/Notifications/VerifyEmailNotification.php
-
import and extend
Illuminate\Auth\Notifications\VerifyEmail -
remove
Illuminate\Bus\Queueable,Illuminate\Contracts\Queue\ShouldQueue,Illuminate\Notifications\Messages\MailMessage,Illuminate\Notifications\Notificationimports -
remove
Queueabletrait -
remove
via,toMail,toArraymethods -
define
$verifyEmailRoutepropertyclass VerifyEmailNotification extends VerifyEmail { public $verifyEmailRoute; // ... }
-
in constructor define nullable
$verifyEmailRouteparameter, assign$verifyEmailRouteparameter to corresponding propertypublic function __construct($verifyEmailRoute) { $this->verifyEmailRoute = $verifyEmailRoute; }
-
override
Illuminate\Auth\Notifications\VerifyEmailnotification verificationUrl method using same code, use$verifyEmailRouteproperty instead of 'verification.verify' when property is not null, importIlluminate\Support\Facades\URL,Illuminate\Support\Carbon,Illuminate\Support\Facades\Configuse Illuminate\Support\Facades\URL; use Illuminate\Support\Carbon; use Illuminate\Support\Facades\Config; /** * Get the verification URL for the given notifiable. * * @param mixed $notifiable * @return string */ protected function verificationUrl($notifiable) { return URL::temporarySignedRoute( $this->verifyEmailRoute ?: 'verification.verify', Carbon::now()->addMinutes(Config::get('auth.verification.expire', 60)), [ 'id' => $notifiable->getKey(), 'hash' => sha1($notifiable->getEmailForVerification()), ] ); }
app/Admin.php
-
override
Illuminate\Auth\MustVerifyEmailtrait sendEmailVerificationNotification using same code, useApp\Notifications\VerifyEmailNotificationinstead ofIlluminate\Auth\Notifications\VerifyEmail, in instantiation pass$verifyEmailRouteparameter as 'admin.verification.verify', importApp\Notifications\VerifyEmailNotificationuse App\Notifications\VerifyEmailNotification; public function sendEmailVerificationNotification() { $this->notify(new VerifyEmailNotification('admin.verification.verify')); }
config/auth.php
-
guards define how users are authenticated, define 'admin-web' / 'admin-api' guards by copying 'web' / 'api' guards and changing provider option to 'admins'
'guards' => [ // ... 'admin-web' => [ 'driver' => 'session', 'provider' => 'admins', ], 'admin-api' => [ 'driver' => 'token', 'provider' => 'admins', 'hash' => false, ], ],
-
providers define how users are retrieved, define 'admins' provider by copying 'users' provider and changing model option to
App\Admin::class'providers' => [ // ... 'admins' => [ 'driver' => 'eloquent', 'model' => App\Admin::class, ], ],
-
passwords define users reset password configurations, define 'admins' reset password configuration by copying 'users' reset password configuration and changing provider option to 'admins'
'passwords' => [ // ... 'admins' => [ 'provider' => 'admins', 'table' => 'password_resets', 'expire' => 60, 'throttle' => 60, ], ],
Laravel defines user home url using HOME constant in RouteServiceProvider we'll do the same for admin
app/Providers/RouteServiceProvider.php
-
define
ADMIN_HOMEconst and set it to '/admin/home'class RouteServiceProvider extends ServiceProvider { public const ADMIN_HOME = '/admin/home'; // ... }
App\Http\Middleware\Authenticate=auth middleware checks if user is authenticated before accessing protected routes if not user is redirected to login route, we'll have to customize redirection logic so that redirection is done based on specified guard
app/Http/Middleware/Authenticate.php
-
App\Http\Middleware\Authenticate=authextendsIlluminate\Auth\Middleware\Authenticatewhich provide the functionality, we'll have to customizeunauthenticatedmethod to retreive request guard, override unauthenticated method using same code, inAuthenticationExceptioninstantiation pass$guardsas a second parameter onredirectTomethod, importIlluminate\Auth\AuthenticationExceptionuse Illuminate\Auth\AuthenticationException; protected function unauthenticated($request, array $guards) { throw new AuthenticationException( 'Unauthenticated.', $guards, $this->redirectTo($request, $guards) ); }
-
in
redirectTomethod add$guardsparameter, redirect based on$guardsto corresponding login routeprotected function redirectTo($request, array $guards) { if (! $request->expectsJson()) { switch (current($guards)) { case 'admin-web': return route('admin.login'); default: return route('login'); } } }
App\Http\Middleware\RedirectIfAuthenticated=guest middleware checks if user is authenticated before accessing protected routes if so user is redirected to home route, we'll have to customize redirection logic so that redirection is done based on specified guard
app/Http/Middleware/RedirectIfAuthenticated.php
-
redirect based on
$guardto corresponding home routepublic function handle($request, Closure $next, $guard = null) { if (Auth::guard($guard)->check()) { switch ($guard) { case 'admin-web': return redirect(RouteServiceProvider::ADMIN_HOME); default: return redirect(RouteServiceProvider::HOME); } } return $next($request); }
Illuminate\Auth\Middleware\EnsureEmailIsVerified=verified middleware checks if user email is verified before accessing protected routes, we'll have to customize it's logic to retrieve user using the specified guard
create a new middleware named EnsureEmailIsVerified
php artisan make:middleware EnsureEmailIsVerified
app/Http/Middleware/EnsureEmailIsVerified.php
-
we'll use original middleware as a template for
App\Http\Middleware\EnsureEmailIsVerifiedmiddleware, replaceApp\Http\Middleware\EnsureEmailIsVerifiedcode with Illuminate\Auth\Middleware\EnsureEmailIsVerified code, add a new nullable parameter called$guard, in$request->usermethod occurrences set$guardparameter to the newly defined parameter<?php namespace App\Http\Middleware; use Closure; use Illuminate\Contracts\Auth\MustVerifyEmail; use Illuminate\Support\Facades\Redirect; class EnsureEmailIsVerified { /** * Handle an incoming request. * * @param \Illuminate\Http\Request $request * @param \Closure $next * @param string|null $redirectToRoute * @return \Illuminate\Http\Response|\Illuminate\Http\RedirectResponse */ public function handle($request, Closure $next, $redirectToRoute = null, $guard = null) { if (! $request->user($guard) || ($request->user($guard) instanceof MustVerifyEmail && ! $request->user($guard)->hasVerifiedEmail())) { return $request->expectsJson() ? abort(403, 'Your email address is not verified.') : Redirect::route($redirectToRoute ?: 'verification.notice'); } return $next($request); } }
app/Http/Kernel.php
-
in
$routeMiddlewareproperty comment existing verified middleware registration and keep it as reference, registerApp\Http\Middleware\EnsureEmailIsVerifiedmiddleware as verifiedprotected $routeMiddleware = [ 'auth' => \App\Http\Middleware\Authenticate::class, 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, 'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class, 'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class, 'can' => \Illuminate\Auth\Middleware\Authorize::class, 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 'password.confirm' => \Illuminate\Auth\Middleware\RequirePassword::class, 'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, // 'verified' => \Illuminate\Auth\Middleware\EnsureEmailIsVerified::class, 'verified' => \App\Http\Middleware\EnsureEmailIsVerified::class, ];
Laravel ships with several pre-built authentication controllers which handles registration, authentication, resetting passwords and email verification, these controllers use traits to include their necessary methods, we'll create admin auth controllers by copying existing ones and making needed adjustments
Group admin controllers in a directory / namespace, create app/Http/Controllers/Admin directory / namespace
Create admin auth controllers, copy app/Http/Controllers/Auth directory as app/Http/Controllers/Admin/Auth
app/Http/Controllers/Admin/Auth/RegisterController.php
-
change namespace to
App\Http\Controllers\Admin\Auth -
import
App\Adminmodel instead ofApp\User -
set
$redirectToproperty toRouteServiceProvider::ADMIN_HOME -
in constructor specify 'admin-web' as the guard that
guest=App\Http\Middleware\RedirectIfAuthenticatedmiddleware should usepublic function __construct() { $this->middleware('guest:admin-web'); }
-
in
validatormethod set unique rule table parameter to 'admins'protected function validator(array $data) { return Validator::make($data, [ 'name' => ['required', 'string', 'max:255'], 'email' => ['required', 'string', 'email', 'max:255', 'unique:admins'], 'password' => ['required', 'string', 'min:8', 'confirmed'], ]); }
-
in
createmethod changeUsermodel toAdminprotected function create(array $data) { return Admin::create([ 'name' => $data['name'], 'email' => $data['email'], 'password' => Hash::make($data['password']), 'api_token' => Str::random(80), ]); }
-
RegisterControllerusesIlluminate\Foundation\Auth\RegistersUserstrait showRegistrationForm method to show registration form, override this method using same code, changeview('auth.register')toview('admin.auth.register')public function showRegistrationForm() { return view('admin.auth.register'); }
-
RegisterControllerusesIlluminate\Foundation\Auth\RegistersUserstrait guard method to get the guard to be used during registration, override this method using same code, inAuth::guardmethod pass guard parameter as 'admin-web', importIlluminate\Support\Facades\Authuse Illuminate\Support\Facades\Auth; protected function guard() { return Auth::guard('admin-web'); }
app/Http/Controllers/Admin/Auth/LoginController.php
-
change namespace to
App\Http\Controllers\Admin\Auth -
set
$redirectToproperty toRouteServiceProvider::ADMIN_HOME -
in constructor specify 'admin-web' as the guard that
guest=App\Http\Middleware\RedirectIfAuthenticatedmiddleware should usepublic function __construct() { $this->middleware('guest:admin-web'); }
-
LoginControllerusesIlluminate\Foundation\Auth\AuthenticatesUserstrait showLoginForm method to show login form, override this method using same code, changeview('auth.login')toview('admin.auth.login')public function showLoginForm() { return view('admin.auth.login'); }
-
LoginControllerusesIlluminate\Foundation\Auth\AuthenticatesUserstrait logout method to log the user out, this trait offer loggedOut method which allow customization oflogoutmethod response, override this method, uselogoutmethod response and changeredirect('/')toredirect('/admin'), importIlluminate\Http\Request,Illuminate\Http\Responseuse Illuminate\Http\Request; use Illuminate\Http\Response; protected function loggedOut(Request $request) { return $request->wantsJson() ? new Response('', 204) : redirect('/admin'); }
-
LoginControllerusesIlluminate\Foundation\Auth\AuthenticatesUserstrait guard method to get the guard to be used during authentication, override this method, inAuth::guardmethod pass guard parameter as 'admin-web', importIlluminate\Support\Facades\Authuse Illuminate\Support\Facades\Auth; protected function guard() { return Auth::guard('admin-web'); }
app/Http/Controllers/Admin/Auth/VerificationController.php
-
change namespace to
App\Http\Controllers\Admin\Auth -
set
$redirectToproperty toRouteServiceProvider::ADMIN_HOME -
in constructor specify 'admin-web' as the guard that
auth=App\Http\Middleware\Authenticatemiddleware should usepublic function __construct() { $this->middleware('auth:admin-web'); $this->middleware('signed')->only('verify'); $this->middleware('throttle:6,1')->only('verify', 'resend'); }
-
VerificationControllerusesIlluminate\Foundation\Auth\VerifiesEmailstrait show method to show email verification notice form, override this method using same code, in$request->usermethod pass guard parameter as 'admin-web', changeview('auth.verify')toview('admin.auth.verify'), importIlluminate\Http\Requestuse Illuminate\Http\Request; public function show(Request $request) { return $request->user('admin-web')->hasVerifiedEmail() ? redirect($this->redirectPath()) : view('admin.auth.verify'); }
app/Http/Controllers/Admin/Auth/ConfirmPasswordController.php
-
change namespace to
App\Http\Controllers\Admin\Auth -
set
$redirectToproperty toRouteServiceProvider::ADMIN_HOME -
in constructor specify 'admin-web' as the guard that
auth=App\Http\Middleware\Authenticatemiddleware should usepublic function __construct() { $this->middleware('auth:admin-web'); }
-
ConfirmPasswordControllerusesIlluminate\Foundation\Auth\ConfirmsPasswordstrait showConfirmForm method to show the password confirmation form, override this method using same code, changeview('auth.passwords.confirm')toview('admin.auth.passwords.confirm')public function showConfirmForm() { return view('admin.auth.passwords.confirm'); }
app/Http/Controllers/Admin/Auth/ForgotPasswordController.php
-
change namespace to
App\Http\Controllers\Admin\Auth -
ForgotPasswordControllerusesIlluminate\Foundation\Auth\SendsPasswordResetEmailstrait showLinkRequestForm method to show the form to request a password reset link, override this method using same code, changeview('auth.passwords.email')toview('admin.auth.passwords.email')public function showLinkRequestForm() { return view('admin.auth.passwords.email'); }
-
ForgotPasswordControllerusesIlluminate\Foundation\Auth\SendsPasswordResetEmailstrait broker method to get the broker to be used during password reset, override this method using same code, inPassword::brokermethod pass broker parameter as 'admins', importIlluminate\Support\Facades\Passwordpublic function broker() { return Password::broker('admins'); }
app/Http/Controllers/Admin/Auth/ResetPasswordController.php
-
change namespace to
App\Http\Controllers\Admin\Auth -
set
$redirectToproperty toRouteServiceProvider::ADMIN_HOME -
ResetPasswordControllerusesIlluminate\Foundation\Auth\ResetsPasswordstrait showResetForm method to show the password reset form, override this method, changeview('auth.passwords.reset')toview('admin.auth.passwords.reset'), importIlluminate\Http\Requestuse Illuminate\Http\Request; public function showResetForm(Request $request, $token = null) { return view('admin.auth.passwords.reset')->with( ['token' => $token, 'email' => $request->email] ); }
-
ResetPasswordControllerusesIlluminate\Foundation\Auth\ResetsPasswordstrait broker method to get the broker to be used during password reset, override this method, inPassword::brokermethod pass broker parameter as 'admins', importIlluminate\Support\Facades\Passworduse Illuminate\Support\Facades\Password; public function broker() { return Password::broker('admins'); }
-
ResetPasswordControllerusesIlluminate\Foundation\Auth\ResetsPasswordstrait guard method to get the guard to be used during password reset, override this method, inAuth::guardmethod pass guard parameter as 'admin-web', importIlluminate\Support\Facades\Authuse Illuminate\Support\Facades\Auth; protected function guard() { return Auth::guard('admin-web'); }
Create admin home controller, copy app/Http/Controllers/HomeController.php as app/Http/Controllers/Admin/HomeController.php
app/Http/Controllers/Admin/HomeController.php
-
change namespace to
App\Http\Controllers\Admin\Auth -
import
App\Http\Controllers\Controller -
in constructor specify 'admin-web' as the guard that
auth=App\Http\Middleware\Authenticatemiddleware should usepublic function __construct() { $this->middleware('auth:admin-web'); }
-
in
indexmethod changeview('home')toview('admin.home')public function index() { return view('admin.home'); }
routes/web.php
-
register admin route group and set 'prefix' option to 'admin', 'namespace' option to 'Admin' and 'as' option to 'admin.'
Route::group(['prefix' => '/admin', 'namespace' => 'Admin', 'as' => 'admin.'], function () { // ... });
-
copy user routes into admin group
-
in '/' route change
view('welcome')toview('admin.welcome')Route::get('/', function () { return view('admin.welcome'); });
-
in '/confirmed' route pass auth middleware guard parameter as 'admin-web' and password.confirm middleware
$redirectToRouteparameter as 'admin.password.confirm'Route::get('/confirmed', function () { return 'password confirmed'; })->middleware(['auth:admin-web', 'password.confirm:admin.password.confirm']);
-
in '/verified' route pass verified middleware
$redirectToRouteparameter as 'admin.verification.notice' and guard parameter as 'admin-web'Route::get('/verified', function () { return 'email verified'; })->middleware('verified:admin.verification.notice,admin-web');
Laravel ships with a user demo api route, we'll add one for admin
routes/api.php
-
copy '/user' route and register it as '/admin', set auth middleware and
$request->usermethod guard parameter to 'admin-api'Route::middleware('auth:admin-api')->get('/admin', function (Request $request) { return $request->user('admin-api'); });
Create a layout for admin, copy resources\views\layouts\app.blade.php as resources\views\layouts\admin.blade.php
resources/views/layouts/admin.blade.php
-
change
url('/')tourl('/admin') -
pass
@guestdirective guard parameter as 'admin-web' -
add 'admin.' route name prefix to auth routes
-
in
Auth::userspecify the guard that auth facade should use, chainguardmethod and pass guard parameter as 'admin-web'{{ Auth::guard('admin-web')->user()->name }}
Group admin views in a directory, create resources/views/admin directory
Create admin welcome view, copy resources/views/welcome.blade.php as resources/views/admin/welcome.blade.php
resources/views/admin/welcome.blade.php
- add 'admin.' route name prefix to auth routes
- set
@authdirective guard parameter to 'admin-web' - change
url('/home')tourl('/admin/home')
Create admin auth views, copy resources/views/auth as resources/views/admin/auth
resources/views/admin/auth/register.blade.php
- change
@extends('layouts.app')to@extends('layouts.admin') - add 'admin.' route name prefix to auth routes
resources/views/admin/auth/login.blade.php
- change
@extends('layouts.app')to@extends('layouts.admin') - add 'admin.' route name prefix to auth routes
resources/views/admin/auth/verify.blade.php
- change
@extends('layouts.app')to@extends('layouts.admin') - add 'admin.' route name prefix to auth routes
resources/views/admin/auth/passwords/confirm.blade.php
- change
@extends('layouts.app')to@extends('layouts.admin') - add 'admin.' route name prefix to auth routes
resources/views/admin/auth/passwords/email.blade.php
- change
@extends('layouts.app')to@extends('layouts.admin') - add 'admin.' route name prefix to auth routes
resources/views/admin/auth/passwords/reset.blade.php
- change
@extends('layouts.app')to@extends('layouts.admin') - add 'admin.' route name prefix to auth routes
Create admin home view, copy resources\views\home.blade.php as resources\views\admin\home.blade.php
resources\views\admin\home.blade.php
- change
@extends('layouts.app')to@extends('layouts.admin')
Now that we've finished we should check that multi auth is working by trying available actions on user and admin. Finally i want to say that Laravel flexibility is what made this implementation that simple so the next time you look for something that's not available out of the box get the shovel and start digging