總結
Auth中間件用於定義未登錄用戶只能操作哪些權限
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異常信息拒絕訪問。
使用授權時需要注意兩個地方
並不需要檢查$currentUser(當前登錄用戶實例)是否為null。框架會自動為其所有權限返回false
調用時,默認情況下,不需要傳遞當前登錄用戶到該方法內。框架會自動加載當前登錄用戶。
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('/'); //默認重定向的頁面