Controller中提供了對應的方法讓使用者對資源進行讀取/建立/更新/刪除等操作(以ProjectController為例):
ProjectController方法|HTTP方法|操作|URL
------------- | -------------| -------------
index|GET|讀取所有計畫資料|projects
show|GET|讀取一筆計畫資料|projects/{project}
store|POST|建立一筆計畫資料|projects
update|PUT/PATCH|更新一筆計畫資料|projects/{project}
destory|DELETE|刪除一筆計畫資料|projects/{project}
控制權限有一些方法,介紹如下:
protected function isUserOwnerOrMemberOfProject(Task $task)
{
if (
Auth::user()->isNot($task->project->owner)
&& !$task->project->members->contains(Auth::user())
) {
abort(403);
}
}
由於權限設定為計畫擁有者或者是被邀請的成員才能夠進到更新任務的頁面並更新任務,所以這個方法用來判斷目前登入的使用者是否是計畫擁有者或者是成員,如果不是,則會回傳403給使用者。
PS Laravel有提供一些方法可以判斷是否需要回傳403:abort/abort_if/abort_unless
權限 | 使用情境 | 好處 |
---|---|---|
Gate | 不適用Policy | 很有彈性,可以搭配Policy使用,也可以自定義權限規則 |
Policy | Policy需要跟某個MODEL或某種資源連結在一起作權限管理 | 由於Policy會跟某個MODEL或資源連結,比起Gate可以集中對該MODEL的讀取/建立/更新/刪除等權限管理 |
(1) 在AuthServiceProvider註冊Policy:
class AuthServiceProvider extends ServiceProvider
{
...
protected $policies = [
Project::class => ProjectPolicy::class,
];
...
}
(2) 如果有加-m參數,則會在ProjectPolicy中自動創建以下方法(與Controller方法對應):
Controller方法 | Policy方法 |
---|---|
index | viewAny |
show | view |
create | create |
store | create |
edit | update |
update | update |
destroy | delete |
PS 如果不需要用到那麼多方法,可以不需要-m
(3) 制定規則
這是ProjectPolicy的權限
class ProjectPolicy
{
use HandlesAuthorization;
/**
* Determine whether the user can view the model.
*
* @param \App\User $user
* @param \App\Project $project
* @return mixed
*/
public function view(User $user, Project $project)
{
return $project->members->contains($user)|| $user->is($project->owner);
}
/**
*
* @param \App\User $user
* @param \App\Project $project
* @return mixed
*/
public function invite(User $user,Project $project)
{
return $user->is($project->owner);
}
/**
* Determine whether the user can update the model.
*
* @param \App\User $user
* @param \App\Project $project
* @return mixed
*/
public function update(User $user, Project $project)
{
return $project->members->contains($user)|| $user->is($project->owner);
}
/**
* Determine whether the user can delete the model.
*
* @param \App\User $user
* @param \App\Project $project
* @return mixed
*/
public function delete(User $user, Project $project)
{
return $user->is($project->owner);
}
}
Gate可以在App\Providers\AuthServiceProvider中定義其權限,可以自定義,也可以使用Policy的方法重新命名,在沒有定義的情況下,會去取用PostPolicy的同名方法:
public function boot()
{
$this->registerPolicies();
//自定義
Gate::define('update-project', function ($user, $project) {
return $user->id === $project->user_id;
});
//使用Policy的方法
Gate::define('update-project', [ProjectPolicy::class, 'update']);
}
Policy可搭配以下方法來管理權限:
(1) Controller中$this->authorize('update',$project)方法。
(2) 加掛Middleware在路徑上。
(3) User Model的can/cant方法。
由於Gate很有彈性,所以不是在上面情境中想控制權限時,我都會想到可以使用Gate。
以InvitationRequest為例,由於這授權規則不是寫在Controller中,所以不能使用$this->authorize()時,
則可以選擇:
(1) 加掛Middleware
Route::post('/projects/{project}/invitations', 'ProjectInvitationController@store')->name('invitation.store')->middleware('can:update,project')
(2)使用Model User
class InvitationRequest extends FormRequest
{
...
public function authorize()
{
return Auth::user()->can('invite',$this->route('project'));
}
...
}
(3)使用Gate(自動確認ProjectPolicy的invite權限)
class InvitationRequest extends FormRequest
{
...
public function authorize()
{
return Gate::allows('invite',$this->route('project'));
}
...
}
明天則是讀Laravel的文件,並做一些關於權限的測試。