laravel已經(jīng)內(nèi)置了一套授權(quán)和權(quán)限分配的功能,我們不用從零開始設(shè)計(jì),這方便了很多。但是, 因?yàn)榧稍诳蚣軆?nèi)的緣故,很多時(shí)候?qū)τ谟脩趔w系甚至有些陌生。本文通過一個(gè)簡單的需求,判斷有效用戶, 逐一為大家實(shí)現(xiàn)。
學(xué)習(xí)時(shí)間
比如在前端有一個(gè)界面,表單的提交參數(shù)如下:
<form class="form-horizontal" role="form" method="POST" action="{{ url('/auth/login') }}">
其中路由 /auth/login 是框架內(nèi)集成的方法。如果有效的數(shù)據(jù)則進(jìn)行驗(yàn)證登陸,如果無效則執(zhí)行錯(cuò)誤邏輯。 那么問題來了,能否手動(dòng)實(shí)現(xiàn)這些邏輯呢。或者說,為了防止無效的暴力請求,在表單開始之初, 能否直接過濾掉一些垃圾請求,過濾掉根本不存在的用戶,或者被禁止的用戶呢?
我們需要在 LoginController 內(nèi)重寫 login 方法。該方法接收一個(gè)請求體:
public function login(IlluminateHttpRequest $request) {}
驗(yàn)證請求參數(shù)是否有效:
$this->validateLogin($request);
如果用戶請求頻次超限被鎖定,則直接返回:
if ($this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
請求參數(shù)正常,接著驗(yàn)證用戶的賬號密碼是否正確:
$ok = $this->guard()->validate($this->credentials($request));
如果賬號密碼錯(cuò)誤,則增加請求計(jì)數(shù)頻次:
$this->incrementLoginAttempts($request);
拋出一個(gè)登陸錯(cuò)誤的提示頁面:
return $this->sendFailedLoginResponse($request);
如果用戶賬號密碼正確,也就是登陸成功了。首先獲取用戶模型:
$user = $this->guard()->getLastAttempted();
接著就是我們需求中所說的業(yè)務(wù)邏輯,可以過濾用戶是否active。使用判斷:
$is_active = $user->active && $this->attemptLogin($request);
如果邏輯通過,則將頁面導(dǎo)航到成功后頁面:
return $this->sendLoginResponse($request);
如果不通過,大概率這用戶是無效非法的,累加其登陸頻次計(jì)數(shù):
$this->incrementLoginAttempts($request);
并給出錯(cuò)誤提示,比較自由,可附加提示信息:
return redirect()->back()->withInput($request->only($this->username(), 'remember'))->withErrors(['active' => 'You must be active to login.']);
至此,登陸篩選的邏輯就完成了。
簡化版
如果像上一節(jié)那樣大改login方法你覺得有些困難,那我們可以來一個(gè)簡化版, 在登陸驗(yàn)證階段,直接驗(yàn)證用戶,并給出錯(cuò)誤提示。
我們知道控制器繼承了 Validator,可以直接使用 validate 方法手動(dòng)構(gòu)建驗(yàn)證規(guī)則:
考慮以下代碼:
protected function validateLogin(Request $request)
{
$this->validate($request, [
$this->username() => 'exists:users,' . $this->username() . ',active,1',
'password' => 'required|string',
]);
}
我們在控制器內(nèi)調(diào)用該方法進(jìn)行過濾驗(yàn)證即可。
寫在最后
本文通過一步步實(shí)現(xiàn)用戶登錄驗(yàn)證流程的方式,將自定義的邏輯嵌入到登錄處理流程內(nèi), 這是一種魔改。當(dāng)然在請求階段,在應(yīng)用邏輯處理到響應(yīng)體之前,你都有機(jī)會(huì)干預(yù)此次請求。 laravel畢竟太靈活了。
HAppy coding :-)
我是@程序員小助手,持續(xù)分享編程知識(shí),歡迎關(guān)注。