Laravel-權限系統

學習筆記,質量不高,純屬加深個人理解,請勿浪費時間閱讀。

總結

  1. Auth中間件用於定義未登錄用戶只能操作哪些權限
  2. policy授權策略定義了當前用戶實例與進行授權的用戶是否匹配,一致才能進一步操作,否則返回403禁止訪問異常

場景:用戶登錄
Auth步驟

  • 找到需要過濾動作的控制器,以中間件形式寫入該類的構造方法中(或可在路由定義,在group by語句前)
    • except:未登錄用戶只能操作數組中的動作,其他均需要登錄用戶方可操作
    • only:未登錄用戶只能操作數組中的動作,其他均需要驗證,常與guest搭配。例只允許guest未登錄用戶訪問註冊頁,相當於已登錄用戶無法訪問註冊頁。
  • 友好轉向:用戶訪問中間件動作中權限受阻時,會自動跳轉到設定頁面。可在RedirectIfAuthenticated.php設定redirect()跳轉的頁面

場景:用戶只能編輯自己
Policy步驟

  • artisan生成 xxxxPolicy 策略文件
    • lara約定了 Policy字眼前的前綴名字爲關聯模型的命名,並自動引入該模型類命名空間。例如生成 UserPolicy策略, 類中會自動引入User模型類的命名空間
  • app/policies中定義策略方法
    • 定義方法,形參依賴注入 當前登錄模型實例進行授權用戶實例的兩個參數 例如 (User $$currentUser, User $user)
    • 方法體寫入判定條件 如 當前登錄模型實例與授權用戶實例的ID比較
  • Providers/Auth/serviceProvider.php$policies屬性中定義授權策略與模型關聯 ,
    • \App\Models\User::class => \App\Policies\UserPolicy::class,
  • 在控制器中調用$this->authorize('update',$user)
    • 第一 個參數對應的是授權類方法中定義的方法名。
    • 第二個參數$user對應的是update授權方法的第二個參數(進行授權的用戶實例)

簡介

Laravel內置了一箇中間件來驗證用戶的身份認證。如果用戶沒有通過身份認證,中間件會重定向到登錄頁面。但如果通過認證,則允許該請求更進一步進入。

可以將中間件想象爲一系列HTTP請求必須經過才能觸發應用的層。每一層都會檢查請求(是否符合某些條件),如果不符合,甚至可以在請求訪問之前完全拒絕。

1.必須先登錄

在用戶控制器中使用構造方法。

$this->middleware('auth',[
    'except'=>['show','create','store']     
]);

middleware方法接收兩個參數:

  • 第一個:中間件名稱
  • 第二個:要進行過濾的動作

其中該中間件還有兩個動作

  • except設定指定動作,數組中的動作將不使用Auth中間件的過濾方法。相當於除了數組中指定動作以外,所有其他的動作都必須登錄用戶才能訪問
  • only白名單,只允許訪問數組中的動作
2.用戶只能編輯自己的資料

當用戶1嘗試更新用戶2的資料時,應彈出403 forbidden禁止訪問異常。
在lara中可以使用policy對用戶操作權限進行驗證,未經授權進行的操作將會返回403

2.1新建一個授權策略類
$ php artisan make:polcy UserPolicy

新建的策略類將會安置在app/Policiies文件夾下。此處體現了【約定優於配置】
這裏寫圖片描述

下面創建一個策略類

public function update(User $currentUser,User $user){
    return $currentUser->id===$user->id;
}

update方法接收兩個參數,第一個參數默認爲當前登錄用戶實例,第二參數則爲要進行授權的用戶實例。當兩個id相同時,則代表兩個用戶是相同用戶。若不同則拋除403異常信息拒絕訪問。

使用授權時需要注意兩個地方

  1. 並不需要檢查$currentUser(當前登錄用戶實例)是否爲null。框架會自動爲其所有權限返回false
  2. 調用時,默認情況下,不需要傳遞當前登錄用戶到該方法內。框架會自動加載當前登錄用戶。
2.2授權關聯

AuthServiceProvider類中對授權策略進行設置。該文件包含一個policies屬性,用於將各種模型對應到管理它們的授權策略上(相當於關聯)。此處需要爲模型指定UserPolicy

接下來,在protected 的policies屬性中添加

\App\Models\User::class=>\App\Policies\UserPolicy::class

授權完畢後,可在控制器中使用authorize方法驗證用戶授權策略。默認的App\Http\Controllers\Controller類包含AuthorizesRequeststrait。該trait提供authorize方法,可以被用於快速授權指定行爲。當無權限運行該行爲時,會拋出HttpException。

authorize方法接收兩個參數

  • 第一個:授權策略名稱(UserPolicy中的授權的update方法)
  • 第二個:進行授權驗證的數據(用戶模型實例,即數據表中指定的字段)
//此處的update對應 UserPolicy的update授權方法
//$user對應的是update授權方法的第二參數。
$this->authorize('update',$user)

調用policy中的update方法時,默認情況下不需要傳遞第一個參數。當前登錄用戶($currentUser)登錄時,框架會自動加載當前登錄用戶

在以下兩處地方分別添加上授權策略驗證

  • edit:當前登錄用戶嘗試編輯時,調用策略類中的update,判斷當前登錄用戶的id是否與模型實例中進行授權的id相同,若不是則無權訪問
  • update同上
2.3友好轉向

未登錄用戶嘗試編輯資料,將會跳轉到登錄頁面,如果用戶再進行登錄,則會重定向到個人中心頁面上。
更好的體驗,應該是將用戶重定向到他之前嘗試訪問的頁面。

redirect()實例提供了一個intended方法(嘗試之意,用戶嘗試訪問的域名).可將頁面重定向到上一次請求嘗試訪問的頁面上,並接收一個默認跳轉地址參數,當上一次請求記錄爲空時,跳轉到默認地址上。

常見場景,可在會話管理(登錄管理)中添加intended方法,

2.4註冊於登錄頁面訪問限制

只讓未登錄用戶訪問登錄頁面和註冊頁面

  • sessionController:登錄管理相關,只允許訪客登錄create(登錄界面),相當設置已登錄的用戶無法訪問登錄頁權限(此時會跳轉到默認頁,需調整)
  • UsersController:用戶管理相關,只允許訪客登錄create(註冊界面),

登錄控制器/用戶控制器:

$this->middleware('guest',[
    //guest指未登錄用戶,訪客
    //only:可理解爲白名單,指定一些只允許未登錄用戶訪問的動作
    'only'=>['create']  
]);
2.5訪問權限受阻返回頁面

訪問Auth定義的中間件權限受阻時,會被跳轉到默認/home頁面。此處需要修改中間件中的redirect()方法並加上友好提醒

文件:app/Http/Middleware/RedirectIfAuthenticated.php,此處的Auth關聯Users控制器(中間件引入了該類)

session()->flash('info', '您已登錄,無需再次操作。');
return redirect('/');      //默認重定向的頁面
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章