【问题标题】:How to use One Laravel Controller with Multiple Guard instead of Duplicating the Controller如何使用一个 Laravel 控制器和多个 Guard 而不是复制控制器
【发布时间】:2020-08-03 11:38:31
【问题描述】:

我有两个卫兵

Admin
User

我还创建了控制器,用户可以在其中管理自己的数据,管理员也可以管理用户数据。所以我创建了两个控制器

Controllers
    Admin
        EducatonBackgroundController
    User
        EducationBackgroundController

在 User/EducationBackgroundController 中,我有这个函数可以获取当前登录用户的教育背景并显示在用户视图上

 public function index(Education $education)
    {
        try {
            $educations = $education->where('user_id',$this->userLoggedID())->with('organization','program','country','city')->get();
            return view('users.education.index',compact('educations'));
        }
        catch (Exception $e) {
            abort(404);
        }
    }

在 Admin/EducationBackgroundController 我有这个功能,它可以获取所有用户的教育背景并显示在管理视图上

 public function index(Education $education)
    {
        try {
            $educations = $education->with('organization','program','country','city','user')->get();
            return view('admin.users.education.index',compact('educations'));
        }
        catch (Exception $e) {
            abort(404);
        }
    }

从观察来看,这些功能相似,但在视图返回和数据获取方面有所不同。

那么我怎样才能创建一个可供管理员和用户警卫使用的控制器,而不是两个警卫的重复控制器和视图。

【问题讨论】:

    标签: laravel laravel-6 laravel-7 laravel-authorization laravel-authentication


    【解决方案1】:

    我通过添加第二组路线做了类似的事情,如下所示:

    <?php
    
        Route::middleware(['auth:admin_api'])->group(function () {
            Route::prefix('admin')->group(function () {
                Route::name('api.admin.')->group(function () {
    
                    ////////////////////////////////////////////////////////////
                    /// PLACE ADMIN API ROUTES HERE ////////////////////////////
                    ////////////////////////////////////////////////////////////
                    Route::apiResource('test','App\Http\Controllers\API\MyController');
                    ////////////////////////////////////////////////////////////
                });
            });
        });
    
        Route::middleware(['auth:api'])->group(function () {
            Route::name('api.')->group(function () {
                ////////////////////////////////////////////////////////////
                /// PLACE PUBLIC API ROUTES HERE ///////////////////////////
                ////////////////////////////////////////////////////////////
                Route::apiResource('test', 'App\Http\Controllers\API\MyController');
                ////////////////////////////////////////////////////////////
            });
        });
    
    

    因此,当管理员用户进入 admin/test 时,它使用 admin auth 保护,而当普通用户进入 /test 时,它使用标准 auth 保护。两者都使用相同的控制器。

    然后我为我的应用创建了一个基本控制器。以下是我在构造函数中使用 guard 来访问路由的方式:

    <?php
    
    
    use Illuminate\Http\Response;
    use App\Http\Controllers\Controller;
    
    class BaseController extends Controller
    {
        protected $user;
    
        protected $isAdmin = false;
    
        public function __construct()
        {
            if(Auth::guard('admin_api')->check()) {
                $this->user = Auth::guard('admin_api')->user();
                $this->isAdmin = true;
            } elseif(Auth::guard('api')->check()) {
                $this->user = Auth::guard('api')->user();
                $this->isAdmin = false;
            } else {
                return response()->json([
                    'message' => 'Not Authorized',
                ], 401);
            }
        }
    
    

    【讨论】:

    • 谢谢。我已经为每个警卫设置了单独的路由,但我希望所有警卫都可以访问一种方法并重定向各自的视图,而不是为每个警卫创建视图和控制器方法
    • 是的。这就是为什么在控制器的构造函数中我让它检查哪个守卫正在用于身份验证。在方法中可以检查if($isAdmin),根据用户的类型采取不同的动作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-12-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多