先前我們留下了一個問題,[Day06 不同角色登入導向],就是使用者登入後,可以透過改變網址的方式去讀取管理者的頁面,我們當時只有在後台首頁做了各自導向的設定,其它頁面的路由則是先不做檢查,不然會一直被導到後台首頁去。
原本我是在考慮是不是做個路徑的陣列去判斷,或是使用Policy來處理,但是冷靜幾天後,想到Laravel的認證其實有一個守門員的機制在,利用這個機制,改造一下原本的middleware就可以了;
首先是先在config\auth.php增檢查用的守門員
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'user' => [
'driver' => 'session',
'provider' => 'users',
],
'admin' => [
'driver' => 'session',
'provider' => 'users',
],
],
由於我會把這個中介層放在 auth 之後,所以我是假設使用者都己經是登入認證過的了;
app\Http\Middleware\RedirectByAuthcatedRole.php
public function handle(Request $request, Closure $next, $guard)
{
//判斷登入者的角色欄位和守門員的名稱是否相同,導向到應該去的頁面
if(Auth::user()->role!==$guard){
// dd(Auth::user()->role,$guard);
switch(Auth::user()->role){
case 'user':
return redirect(RouteServiceProvider::USERHOME);
break;
case 'admin':
return redirect(RouteServiceProvider::HOME);
break;
}
}
//如果角色沒問題就繼續前進
return $next($request);
}
修改一下原本的中介層名稱,比較好識別
app\Http\Kernel.php
protected $routeMiddleware = [
.....略
'role' => \App\Http\Middleware\RedirectByAuthcatedRole::class,
];
最後把後台的路由使用Group語法全部般到同一組middleware中控管
routes\web.php
//在middleware後加上角色當成參數傳入
Route::middleware(['auth', 'verified','role:admin'])->group(function(){
Route::get('/backstage', [BackstageController::class,'controlPanel'])->name('backstage');
Route::get('/backstage/banks',[BankController::class,'index'])->name('backstage.banks');
Route::get('/backstage/quizzes',[QuizController::class,'index'])->name('backstage.quizzes');
Route::get('/backstage/tests',[TestController::class,'index'])->name('backstage.tests');
Route::get('/backstage/groups',[GroupController::class,'index'])->name('backstage.groups');
Route::get('/subjects',[SubjectController::class,'index'])->name('subject.index');
Route::get('/subject/{bank_id}/create',[SubjectController::class,'create'])->name('subject.create');
Route::post('/subject',[SubjectController::class,'store'])->name('subject.store');
Route::get('/subject/edit/{id}',[SubjectController::class,'edit'])->name('subject.edit');
Route::put('/subject/{id}',[SubjectController::class,'update'])->name('subject.update');
Route::delete('/subject/{id}',[SubjectController::class,'destroy'])->name('subject.destroy');
Route::get('/subjects/{bank_id}/upload',[SubjectController::class,'upload'])->name('subjects.upload');
Route::post('/subjects/import',[SubjectController::class,'import'])->name('subjects.import');
Route::get('/bankgroup/{id}/subjects',[BankGroupController::class,'subjectsInGroup'])->name('bankgroup.subjects');
Route::get('/bank/{bank_id}/bankgroup/create',[BankGroupController::class,'create'])->name('bankgroup.create');
Route::post('/bankgroup',[BankGroupController::class,'store'])->name('bankgroup.store');
Route::get('/bankgroup/{id}',[BankGroupController::class,'show'])->name('bankgroup.show');
Route::get('/bankgroup/{id}/edit',[BankGroupController::class,'edit'])->name('bankgroup.edit');
Route::put('/bankgroup/{id}',[BankGroupController::class,'update'])->name('bankgroup.update');
Route::delete('/bankgroup/{id}',[BankGroupController::class,'destroy'])->name('bankgroup.destroy');
Route::get('/bank/{id}/subjects',[SubjectController::class,'subjectsInBank'])->name('bank.subjects');
Route::get('/bank/{id}',[BankController::class,'show'])->name('bank.show');
Route::post('/bank',[BankController::class,'store'])->name('bank.store');
Route::put('/bank/{id}',[BankController::class,'update'])->name('bank.update');
Route::delete('/bank/{id}',[BankController::class,'destroy'])->name('bank.destroy');
});
//使用者後台使用不同的守門員名稱
Route::get('/userhome', [UserController::class,'userCenter'])
->middleware(['auth', 'verified','role:user'])
->name('userhome');
現在不同角色的使用者,就算在網址上直接修改路由,也都會被導到自己應該去的後台去了。