I have created a custom multi-auth system in laravel-5.8 for a college website where every user registers for a specific role: Admin, Faculty, or HOD(Head of Department).
I am making use of the controllers and views which we get after running
php artisan make:auth
Upon registering, all the users are redirecting to default home page, regardless of their roles. The 3 roles are being stored in the Users table as 0, 1, and 2 under column role. I modified the Users table which comes by default.
My login mechanism works well. Users are redirected to the home page of their role. Here is how I do it:
LoginController.php
public function login(Request $request){
if(Auth::attempt(['PID' => $request->PID, 'password' => $request->password])){
$user = User::where('PID',$request->PID)->first();
if($user->role == '0'){
return redirect('home');
}
else{
if($user->role == '1'){
return redirect('hodhome');
}
else{
return redirect('adminhome');
}
}
}
return redirect()->back();
}
This is the route used upon the POST request from login.blade.php
Route::post('/login/custom', 'auth\LoginController@login')->name('login.custom');
But every time I register a new user, it takes users to the faculty home page route, even when they're admins or HODs. Here's the register mechanism:
RegisterController.php (Just showing relevant functions below)
use RegistersUsers;
protected $redirectTo = '/home';
public function __construct()
{
$this->middleware('guest');
}
//validator function and create function after this line
I have tried to make it work properly by doing this: Changing the variable redirectTo
to a function.
//an idea: replace "protected $redirectTo = '/home';" by...
protected function redirectTo(array $data){
if($data['role']=='0'){ return redirect('home'); }
elseif($data['role']=='1'){ return redirect('hodhome'); }
else return redirect('adminhome');
}
But it doesn't work, because I seem to be missing something.
Another bummer is the fact that after login, users can access home pages of other roles. the middleware('auth')
in my routes helps protect against accessing the URLs when not logged in, but it doesn't stop logged in users from accessing other home pages.
Here are the routes to the home pages:
Auth::routes();
//-------------------MULTI AUTH SYSTEM------------------------------------------
Route::post('/login/custom', 'auth\LoginController@login')->name('login.custom');
Route::get('/home', 'HomeController@index')->name('home');
route::get('/adminhome', function () {
return view('adminhome');
})->middleware('auth');
route::get('/hodhome', function () {
return view('hodhome');
})->middleware('auth');
//----------------------------------------------------------------------------
The default welcome.blade.php
too redirects logged in users to faculty's home page:
@if (Route::has('login'))
<div class="top-right links">
@auth
<a href="{{ url('/home') }}">Home</a>
@else
<a href="{{ route('login') }}">Login</a>
@if (Route::has('register'))
<a href="{{ route('register') }}">Register</a>
@endif
@endauth
</div>
@endif
After incorporating changes suggested by @N69S, This is what's happening:
That solution worked. But when an illegal access to a URL is attempted, an error has to be generated.
But instead, user is being sent to the welcome page. This page has only one link in the top right corner, called "HOME". This link does not work when either admin or HOD user is logged in because it routes to '/home'
as shown:
//welcome.blade.php
<body>
<div class="flex-center position-ref full-height">
@if (Route::has('login'))
<div class="top-right links">
@auth
<a href="{{ url('/home') }}">Home</a>
@else
<a href="{{ route('login') }}">Login</a>
@if (Route::has('register'))
<a href="{{ route('register') }}">Register</a>
@endif
@endauth
</div>
@endif
<div class="content">
<div class="title m-b-md text-center">
COLLEGE ADMINISTRATION <br> SYSTEM
</div>
</div>
</div>
</body>
How do I change this view file to send logged in user to his role's HOME?
One complete and correct solution would be to separate the entities (HOD, Admin, User) and configure the auth for each one (auth:hod, auth:admin, auth)
Another solution would be to make 3 separate middleware and group your routes with one of them accordingly.
btw, redirectTo()
method does not take parameters. From Illuminate\Foundation\Auth\RedirectsUsers
trait
/**
* Get the post register / login redirect path.
*
* @return string
*/
public function redirectPath()
{
if (method_exists($this, 'redirectTo')) {
return $this->redirectTo();
}
return property_exists($this, 'redirectTo') ? $this->redirectTo : '/home';
}
---------------Edit
For the 3 middleware solution, you can use the command php artisan make:middleware Admin
, this will create the Class file app/Http/ Middleware/Admin.php
.
in the handle
method, you can do something like
public function handle($request, Closure $next)
{
if(auth()->user() && auth()->user()->role == 2){
return $next($request);
}
return redirect(‘login’)->with(‘error’,’You have not admin access’);
}
and do the same for the HOD
To use it like auth
in the routes, add the middleware in the kernel App\Http\Kernel.php
in $routeMiddleware
protected $routeMiddleware = [
//....,
//....,
'admin' => \App\Http\Middleware\Admin::class,
];