Laravel 多重身份验证 - 管理员保护
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/47534712/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Laravel Multi Auth - Admin Guard
提问by Srikanth Gopi
I have two guards in laravel
我在 Laravel 有两个守卫
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
//Our Admin custom driver
'web_admin' => [
'driver' => 'session',
'provider' => 'admins',
],
],
and providers
和提供者
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
//Admin user provider
'admins' => [
'driver' => 'eloquent', //We are using eloquent model
'model' => App\Admin::class,
],
],
The default is
默认是
'defaults' => [
'guard' => 'web',
'passwords' => 'users',
],
When i log in as admin and try to access the user profile it asks me to login as user which is normal. But what im looking for is, admin should be able to access whole site as admin login.
当我以管理员身份登录并尝试访问用户配置文件时,它要求我以正常用户身份登录。但是我要寻找的是,管理员应该能够以管理员登录身份访问整个站点。
The reason i choose multi auth over rbac is because i have 5 types of users and each have different registration fields and login. Each user have a set of tools too.
我选择多重身份验证而不是 rbac 的原因是因为我有 5 种类型的用户,并且每一种都有不同的注册字段和登录信息。每个用户也有一套工具。
So i want admin guard to be able to access all guards too.
所以我希望管理员守卫也能够访问所有守卫。
Business guard to be able to access only users guard.
业务守卫只能访问用户守卫。
App/Http/Controllers/AdminAuth/LoginController
应用程序/Http/Controllers/AdminAuth/LoginController
<?php
//LoginController.php
namespace App\Http\Controllers\AdminAuth;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
//Class needed for login and Logout logic
use Illuminate\Foundation\Auth\AuthenticatesUsers;
//Auth facade
use Auth;
class LoginController extends Controller
{
//Where to redirect admin after login.
protected $redirectTo = '/admin/home';
//Trait
use AuthenticatesUsers;
//Custom guard for admin
protected function guard()
{
return Auth::guard('web_admin');
}
//Shows admin login form
public function showLoginForm()
{
return view('admin.auth.login');
}
}
App/Http/Controllers/Auth/LoginController
应用程序/Http/Controllers/Auth/LoginController
<?php
namespace App\Http\Controllers\Auth;
use Socialite;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
class LoginController extends Controller
{
/*
|--------------------------------------------------------------------------
| Login Controller
|--------------------------------------------------------------------------
|
| This controller handles authenticating users for the application and
| redirecting them to your home screen. The controller uses a trait
| to conveniently provide its functionality to your applications.
|
*/
use AuthenticatesUsers;
/**
* Where to redirect users after login.
*
* @var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* @return void
*/
public function __construct()
{
$this->middleware('guest')->except('logout');
}
/**
* Redirect the user to the GitHub authentication page.
*
* @return \Illuminate\Http\Response
*/
public function redirectToProvider($social)
{
return Socialite::driver($social)->redirect();
}
/**
* Obtain the user information from GitHub.
*
* @return \Illuminate\Http\Response
*/
public function handleProviderCallback($social)
{
$user = Socialite::driver($social)->user();
// $user->token;
}
}
Similarly i have created middleware for admin too in App/Https/Middleware/AuthenticateAdmin.php
同样,我也在 App/Https/Middleware/AuthenticateAdmin.php 中为管理员创建了中间件
<?php
//AuthenticateAdmin.php
namespace App\Http\Middleware;
use Closure;
//Auth Facade
use Auth;
class AuthenticateAdmin
{
public function handle($request, Closure $next)
{
//If request does not comes from logged in admin
//then he shall be redirected to admin Login page
if (! Auth::guard('web_admin')->check()) {
return redirect('/admin/login');
}
return $next($request);
}
}
And RedirectIfAdminAuthenticated
和 RedirectIfAdminAuthenticated
<?php
//RedirectIfAdminAuthenticated.php
namespace App\Http\Middleware;
use Closure;
//Auth Facade
use Auth;
class RedirectIfAdminAuthenticated
{
public function handle($request, Closure $next)
{
//If request comes from logged in user, he will
//be redirect to home page.
if (Auth::guard()->check()) {
return redirect('/home');
}
//If request comes from logged in admin, he will
//be redirected to admin's home page.
if (Auth::guard('web_admin')->check()) {
return redirect('/admin/home');
}
return $next($request);
}
}
RedicrectIfAuthenticated
重定向如果已验证
<?php
namespace App\Http\Middleware;
use Closure;
use Illuminate\Support\Facades\Auth;
class RedirectIfAuthenticated
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
* @param string|null $guard
* @return mixed
*/
public function handle($request, Closure $next, $guard = null)
{
if (Auth::guard($guard)->check()) {
return redirect('/home');
}
return $next($request);
}
}
回答by shushu304
Further to our correspondence
进一步我们的通信
1.
1.
If you have many types of users... so i suggest you to change your logic and make the Admin as User too... remove the admins and in the users add field "type" or something like that... and work with field to check if user is admin or have permission / access to some parts of the system... and if the user "type" is "admin" so he will have access to all parts too.
如果您有多种类型的用户...所以我建议您更改逻辑并将管理员设置为用户...删除管理员并在用户中添加字段“类型”或类似内容...并使用字段来检查用户是否是管理员或有权/访问系统的某些部分......如果用户“类型”是“管理员”,那么他也可以访问所有部分。
so you mean remove multi auth and go for RBAC. But i have a requirement where i need to use multi auth and each guard has their own RBAC For example, admin guard roles are manager, support and so. Business guard roles are vendors, sellers and so.
yes this is what i mean. I did similar thing on one of the systems that i developed, and i added one more guard so all the "logged in" routes pass in (like auth) and there i'm checking the requested rout and action and check if the user type is allow to access this action, and if not i redirected him to somewhere else (in my case to main dashboard page).
所以你的意思是删除多重身份验证并使用 RBAC。但是我有一个要求,我需要使用多重身份验证,并且每个警卫都有自己的 RBAC 例如,管理员警卫角色是经理、支持等。业务守卫角色是供应商、卖家等。
是的,这就是我的意思。我在我开发的其中一个系统上做了类似的事情,我又添加了一个守卫,所以所有“登录”路由都传入(如身份验证),然后我正在检查请求的路由和操作,并检查用户是否键入允许访问此操作,如果没有,我将他重定向到其他地方(在我的情况下是主仪表板页面)。
add new middleware
添加新的中间件
php artisan make:middleware Permissions
in app\Http\Kernel.php, add to protected $routeMiddleware new middleware
在 app\Http\Kernel.php 中,添加到受保护的 $routeMiddleware 新中间件
'permissions' => \App\Http\Middleware\Permissions::class,
in Routes web add the desire routs for logged in and add the middleware permissions ... pay attention to the asdefinition
在 Routes web 中添加想要登录的路由并添加中间件权限...注意as定义
Route::group(['middleware'=>['auth', 'permissions']], function() {
// any of your routs ... for example
Route::get('/', [
'uses'=>"UserController@getUsers",
'as'=>"users"
]);
Route::get('/{id}', [
'uses'=>"UserController@getUserEdit",
'as'=>"users.edit"
]);
});
in the new middleware app\Http\Middleware\Permissions.php, adjust the public function handleand add there the users level logic... pay attention that for the switch case checking the as... the same asthat defined in the routs web file.
在新的中间件应用程序\ HTTP \中间件\ Permissions.php,调整公共职能手柄,并添加有用户级别的逻辑......注意,对于开关的情况下检查作为...相同的是,在击溃定义网络文件。
add more check as you need for the logged in user "type"... Admin, Support ... and so on as you have in the system.
根据需要为登录用户“类型”添加更多检查...管理员,支持...等等,就像您在系统中一样。
public function handle($request, Closure $next, $guard = null)
{
$user = $request->user();
$actions = $request->route()->getAction();
switch( $actions['as'] ) {
case "users":
if( ! $user->isAdmin() ) {
//return redirect()->route("dashboard");
}
break;
case "users.edit":
if( ! $user->isAdmin() ) {
}
break;
// add more cases as you need and check the user "type"
default:
break;
}
return $next($request);
}
if you have a lot of routs... so maybe it will be better to add few "little" middleware and for every route group / prefix ... check if user allow to access this prefix. for example... add SupportMiddleware / SalesMiddleware ... and in every one of them you can just check the user type and if it's fit to the current group of routes.
如果你有很多路由......所以也许最好为每个路由组/前缀添加一些“小”中间件......检查用户是否允许访问这个前缀。例如...添加 SupportMiddleware / SalesMiddleware ... 在每一个中,您都可以检查用户类型以及它是否适合当前的路由组。
回答by Salman Momin
Simply, seperate your guards with , (comma)then all of the listed guards can access those routes.
简单地,用,(逗号)分隔你的守卫,然后所有列出的守卫都可以访问这些路线。
Example:
例子:
Route::group(['middleware'=>'auth:web,web_admin'], function() {
//Now this routes can be accessible by both admin as well as
});

