问题
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
回答1:
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');
}
if ($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.
回答2:
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.phpfile
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.phpfile, 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.
回答3:
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());
}
来源:https://stackoverflow.com/questions/40048732/laravel-5-3-login-redirect-to-different-pages-for-multiple-users