3分鐘短文:任命管理員,給Laravel普通使用者提權

程式設計師小助手 發表於 2020-10-17

引言

系統內使用User表記錄使用者的屬性,各自維護使用者自身的關聯資料。

有一些前端頁面也會需要分別根據身份展示不同級別的內容。

img

本期為大家說一說給普通使用者提權為 管理員。

資料準備

我們希望在users表內指定使用者的身份,比如任命為管理員,則可以展示更多的資料資源。

我們在users表內追加一個欄位 is_admin 用於標記使用者的管理員身份,使用命令建立遷移檔案:

php artisan make:migration add_is_admin_to_user_table --table=users

首先填充 up 方法用於遷移執行的邏輯:

public function up()
{
    Schema::table('users', function(Blueprint $table)
    {
        $table->boolean('is_admin')->default(false);
    });
}

如果遷移失敗,進行回滾使用的 down 方法:

public function down() 
{
    Schema::table('users', function(Blueprint $table)
    {
        $table->dropColumn('is_admin');
    }
}

完成編輯後儲存,並執行遷移指令:

php artisan migrate

為了測試,我們使用mysql客戶端直接連線資料庫,並手動指定一個管理員,使用下面的SQL語句:

update users set is_admin = true where email = '[email protected]';

路由

為了區別於普通使用者的前端頁面,我們使用新的名稱空間 Admin 放置管理員相關的程式碼。首先建立控制器:

php artisan make:controller Admin/UsersController

然後新增路由,編輯 routes/web.php 檔案並新增以下內容:

Route::group(['prefix' => 'admin', 'namespace' => 'Admin'], function()
{
    Route::resource('user', 'UsersController');
});

注意我們使用了兩個關鍵的引數,

  • prefix : 也就是該組內的所有路由地址,使用 prefix 最為字首
  • namespace : 名稱空間,指定該組內所有的控制器,均位於該名稱空間下。

控制器

上一節的路由我們定義的是資源路由,使用restful風格宣告。下面建立 app/Http/Controllers/admin/UsersController.php 檔案,並實現 index 方法。程式碼內容如下:

public function index()
{
    $users = User::orderBy('created_at', 'desc')->get();
    return view('admin.users.index')->withUsers($users);
}

我們還需要一個檢視檔案,承載上述的資料。建立目錄 resources/views/admin/users/index.blade.php,簡單建立一個模板:

<h1>Registered Users</h1>
<ul>
    @forelse ($users as $user)
        <li>{{ $user->name }} ({{ $user->email }})</li>
    @empty
        <li>No registered users</li>
    @endforelse
</ul>

展示的是所有使用者的資訊。這顯然必須擁有較高的許可權。所以我們在給資料之前,要識別使用者是否管理員:

if (Auth::user()->is_admin != true) {
    return redirect()->route('home')->withMessage('Access denied!');
}

如果不是就路由到首頁。這樣的判斷,如果頁面多了起來之後,每次都要在控制器內敲寫,著實麻煩。所以,必須使用更靠前的驗證,也就是 中介軟體

中介軟體

中介軟體可以註冊給路由檔案,在命中路由後,呼叫中介軟體進行身份識別,這是不錯的選擇。

使用命令列建立中介軟體檔案:

php artisan make:middleware AdminAuthentication

生成的檔案位於 app/Http/Middleware/ 目錄下,編輯 AdminAuthentication 檔案,並實現程式碼邏輯:

namespace App\Http\Middleware;
use Closure;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Http\RedirectResponse;

class AdminAuthentication {
    public function handle($request, Closure $next)
    {
        if ($request->user())
        {
            if ($request->user()->is_admin == true)

            {
                return $next($request);
            }
        }

        // 驗證不通過
        return new RedirectResponse(url('/'));
    }
}

然後在 app/Http/Kernel.php 檔案內註冊該中介軟體,並命名:

protected $routeMiddleware = [
    'admin' => \App\Http\Middleware\AdminAuthentication::class,
];

修改 路由 一節中宣告的路由組,引入中介軟體:

Route::group(
[
    'prefix' => 'admin',
    'namespace' => 'admin',
    'middleware' => 'admin'
], function()
{
    Route::resource('users', 'UsersController');
});

寫在最後

本文又是一個功能齊全卻又mini小巧的短文,詳細闡述瞭如何為users表新增管理員功能。

通過註冊路由到中介軟體的使用,又一次體驗了laravel各個元件協同作用的能力!

Happy coding :-)

我是@程式設計師小助手,專注程式設計知識,圈子動態的IT領域原創作者

本作品採用《CC 協議》,轉載必須註明作者和本文連結
write-less-do-more-make-you-out-of-door