首页 > 解决方案 > 如何使用一个 Laravel 控制器和多个 Guard 而不是复制控制器

问题描述

我有两个卫兵

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);
        }
    }

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

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

标签: laravellaravel-6laravel-7laravel-authorizationlaravel-authentication

解决方案


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

<?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);
        }
    }


推荐阅读