認證與授權的差異
認證(Authentication) 用來確認使用者「是誰」,登入處理就是代表性例子。 授權(Authorization) 用來判斷該使用者「能做什麼」。例如:只能編輯自己的貼文、只有管理員能修改設定等控制。 在認證實作完登入功能後,下一步就是授權。Laravel 的授權功能提供 Gates 與 Policies 兩種方式。使用哪一種取決於實際情境。
Gate
Gate 是以 Closure 為基礎、簡單的授權檢查。適合用在不綁定特定模型的權限判定。透過 Gate 的授權流程
定義 Gate
Gate 於App\Providers\AppServiceProvider 的 boot 方法中使用 Gate::define() 定義。
用 Gate 檢查權限
在 Controller 中使用 Gate 檢查權限,可使用Gate::allows() 或 Gate::denies()。
用 Gate::authorize() 拋出例外
若希望在無權限時自動回傳 403,可使用Gate::authorize(),可省下寫 abort(403) 的功夫。
管理員繞過(before 方法)
若想賦予管理員所有權限,可使用Gate::before()。
before Closure 回傳非 null 的值時,該結果即為最終權限判定。若回傳 null 或不回傳任何值,則進入一般的 Gate 判定。
Blade 模板中的 @can / @cannot
在模板中使用 Gate 判定時,可用@can 與 @cannot 指令。
Policy
Policy 是把與特定模型相關的授權邏輯整理成類別。對Post 模型的建立、瀏覽、編輯、刪除權限管理,Policy 比 Gate 更合適。
透過 Policy 的授權流程
產生 Policy
使用make:policy Artisan 指令產生 Policy 類別。
--model 選項。
app/Policies/PostPolicy.php。
模型與 Policy 的自動探索
Laravel 預設會依命名慣例自動發現 Policy。- 模型:
app/Models/Post.php - Policy:
app/Policies/PostPolicy.php
若不遵循命名慣例或想手動註冊,可在 在 Laravel 13 中,也可在模型上加上
AppServiceProvider 的 boot 方法中使用 Gate::policy()。#[UsePolicy] 屬性以宣告式方式註冊。實作 Policy 方法
使用--model 選項產生的 Policy 已包含對應標準 CRUD 動作的方法。
管理員繞過(before 方法)
在 Policy 內也可定義before 方法,賦予管理員所有權限。
before Callback 的執行順序
在 Controller 中使用 Policy
authorize() 方法
Laravel 的 Controller 具備authorize() 輔助方法(若不使用 base Controller,則改用 Gate::authorize())。
- User::can() / cannot()
用 authorizeResource() 一次註冊 RESTful Policy
在建構子中呼叫authorizeResource(),會自動將 Controller 各動作對應到 Policy 方法。
在 Middleware 中授權
要在路由層級進行授權檢查,可使用can middleware。
can 方法的更簡潔寫法:
在 Blade 模板使用 Policy
註冊 Policy 後,Blade 的@can / @cannot 指令也會自動使用 Policy。
實務範例:部落格文章的權限管理
在部落格應用中實作「只有作者能編輯或刪除自己的文章」權限的範例。1
產生 Policy
2
實作 Policy 方法
3
在 Controller 加入 authorizeResource()
4
在 Blade 模板加入權限檢查
總結
Gate 與 Policy 的選用
Gate 與 Policy 的選用
- Gate:不綁定特定模型的簡易權限判定。像是管理員儀表板的存取或全域設定的修改權限。
- Policy:針對模型的 CRUD 操作權限管理。可依
Post、Order、Comment等資源分別建立 Policy 類別。
常用 API 總覽
常用 API 總覽
常用 Artisan 指令
常用 Artisan 指令