I have Laravel 5.3 with three different types of users. I want them to be redirected to different dashboard pages after logging in. For example:
user -> login -> user-dashboard
admin -> login -> admin-dashboard
I have created a middleware called CheckRole
:
public function handle($request, Closure $next)
{
if($request->user() === null) {
return response("Insufficient Permissions" , 401);
}
$actions = $request->route()->getAction();
$roles = isset($actions['roles']) ? $actions['roles'] : null;
if($request->user()->hasAnyRole($roles) || !$roles) {
return $next($request);
}
return response("Insufficient Permissions" , 401);
}
Routes
Route::group(['middleware' => ['auth','roles'], 'roles' => 'Admin'], function () {
// Routes here
}
Roles are working perfectly.
Now redirectTo= '';
in the LoginContoller
points to one view only. I have checked the documentation and I believe this has something to do with guards which have no explanation on how to set it up.
I have also seen multiauth, but I do not think it is wise to create different tables for different users and hence looking for an alternate answer.
Any Suggestion would be appreciated.
My tables are like:
Table users
id | name | email
---------
1 | John | john@blah.com
2 | Michael | michael@blah.com
Table roles
id | name
---------
1 | Admin
2 | PrivilegedMember
3 | Subscriber
Table user_role
id | user_id | role_id
----------------------
1 | 1 | 1
2 | 2 | 2
This might be a duplicate of the below question but the answer provided leaves without explaining multiple redirections.
Multiple Authentication in Laravel 5.3
Implement an authenticated()
method in your LoginController
and add the redirection logic there:
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
use AuthenticatesUsers;
// ...
/**
* The user has been authenticated.
*
* @param \Illuminate\Http\Request $request
* @param mixed $user
*
* @return mixed
*/
protected function authenticated(Request $request, $user)
{
if($user->hasRole('Admin')) {
return redirect()->intended('admin');
} elseif ($user->hasRole('PrivilegedMember')) {
return redirect()->intended('PriviligedMember/index');
}
}
// ...
}
The method is called after the user is authenticated. See the last two lines of sendLoginResponse
:
/**
* Send the response after the user was authenticated.
*
* @param \Illuminate\Http\Request $request
*
* @return \Illuminate\Http\Response
*/
protected function sendLoginResponse(Request $request)
{
$request->session()->regenerate();
$this->clearLoginAttempts($request);
return $this->authenticated($request, $this->guard()->user())
?: redirect()->intended($this->redirectPath());
}
So it's a perfect candidate for such logics.
One other note on your own answer, the AuthenticatesUser
is a trait that horizontally extends the LoginController
, you can safely override any of its methods in your controller without touching the core files.
The best way (that I've found) to do that is using Traits. What are we going to do is bassically the same but less complicated and more structured:
1. Instead of creating two tables, our User Model will have a role field, in my case I'll have: 'admin', 'employee' and 'user'.
2. We are going to create a Traits Folder, in this case it will be placed in App/Http
.
3. We are going to create a new file and call it RedirectTrait.php
inside that folder with this content:
<?php
namespace App\Http\Traits; // Or the place where the trait is stored (step 2)
use Illuminate\Http\Request;
trait RedirectTrait
{
/**
* Where to redirect users after register/login/reset based in roles.
*
* @param \Iluminate\Http\Request $request
* @param mixed $user
* @return mixed
*/
public function RedirectBasedInRole(Request $request, $user) {
$route = '';
switch ($user->role) {
# Admin
case 'admin':
$route = '/admin/dashboard/route'; // the admin's route
break;
# Employee
case 'employee':
$route = '/employee/dashboard/route'; // the employee's route
break;
# User
case 'user':
$route = '/user/dashboard/route'; // the user's route
break;
default: break;
}
return redirect()->intended($route);
}
}
As you can see, we can 'play' with the redirections, but intended is necessary According laravel documentation:
The intended method on the redirector will redirect the user to the URL they were attempting to access before being intercepted by the authentication middleware. A fallback URI may be given to this method in case the intended destination is not available.
4. Finally, we'll place the trait and call it:
- In the
App/Http/Controllers/Auth/LoginController.php
file
use Illuminate\Http\Request; // Add
use App\Http\Traits\RedirectTrait; // Call the trait
class LoginController extends Controller
{
...
use RedirectTrait; // Use the trait
/**
* The user has been authenticated.
*
* @param \Illuminate\Http\Request $request
* @param mixed $user
* @return mixed
*/
protected function authenticated(Request $request, $user)
{
return $this->RedirectBasedInRole($request, $user);
}
...
}
We're overwriting the 'authenticated' method placed in Illuminate\Foundation\Auth\AuthenticatesUsers
(which is empty by the way)
- We'll do the same in the
App/Http/Controllers/Auth/RegisterController.php
file, but the method will have a different name naturally:
/**
* The user has been registered.
*
* @param \Illuminate\Http\Request $request
* @param mixed $user
* @return mixed
*/
protected function registered(Request $request, $user)
{
return $this->RedirectBasedInRole($request, $user);
}
We're overwriting the 'redirected' method stored in Illuminate\Foundation\Auth\RegistersUsers
, and is empty as well.
5. Enjoy :D
PS. The reset password redirect is another history.
It looks like the below solution over rides the process and does the job. But I do not think it is the right way as we are tinkering with Core files. Some body please throw a light on this.
Go to AuthenticatesUser.php trait.
locate SendLoginResponse(Request $request)
Before returning the default path add your conditions.I have changed it to below
protected function sendLoginResponse(Request $request)
{
$request->session()->regenerate();
$this->clearLoginAttempts($request);
if(Auth::User()->hasRole('Admin')) {
return redirect()->intended('admin');
} elseif (Auth::User()->hasRole('PrivilegedMember')) {
return redirect()->intended('PriviligedMember/index');
}
return $this->authenticated($request, $this->guard()->user())
?: redirect()->intended($this->redirectPath());
}