laravel 登入重寫
許可權控制是幾乎每套成熟系統不可缺少的一部分,我們使用的許可權控制方法是rbac,我將在這個系列的文章一步步完成一個比較複雜的rbac許可權控制。
rbac許可權控制是一個非常成熟的許可權控制系統,其原理是給每個使用者一個或多個角色 而每個角色對系統相應模組有存取權限,具體理論知識不多介紹。在我完成這個許可權控制系統中,我將普通使用者和管理使用者分開在資料庫中儲存,我們先完成普通使用者的登入,這一部分相對於管理使用者會比較簡單,同時也讓大家理解下登入的流程。
未登入使用者跳轉到登入頁面
當我們訪問某些一定要登入後才能使用的功能時 我們往往會有一個功能就是 如果沒有登入的使用者,就會直接跳轉到登入功能 在laravel已經提供的代碼中我們可以非常輕鬆完成這個功能
php
class HomeController extends Controller { public function __construct() { $this->middleware('auth'); } public function index() { echo url('/home'); echo '這是首頁'; }}
我們在隨便一個需要進行登入才能使用的控制器中使調用auth這個控制器就可以了,這個控制器會去檢查session中是否有登入資訊來進行判斷是否有沒有登入 那麼這個'auth'中介軟體在哪呢?
laravel中所有中介軟體都在app/Http/Kernel中註冊
php protected $routeMiddleware = [ 'auth' => 'App\Http\Middleware\Authenticate', 'auth.basic' => 'Illuminate\Auth\Middleware\AuthenticateWithBasicAuth', 'guest' => 'App\Http\Middleware\RedirectIfAuthenticated', 'admin_auth' => 'App\Http\Middleware\AdminPermissionCheck', ];
這個數組中key是中介軟體的別名 value是中介軟體的路徑 由此我們可以找到別名為auth的中介軟體
找到App\Http\Middleware\Authenticate
php public function handle($request, Closure $next) { if ($this->auth->guest()) { if ($request->ajax()) { return response('Unauthorized.', 401); } else { //這個方法會跳轉到Auth控制器的getLogin方法 //如果沒有 那麼會自動跳轉的視圖檔案夾下的auth login return redirect()->guest('auth/login'); } } return $next($request); }
handle方法是調用中介軟體時調用的方法 其中guest是判斷有沒有登入的方法 這裡我們最有可能需要改的地方就是如果沒有登入跳轉的方法 如上面代碼所示 跳轉的路徑為auth/login(這個路徑已經在路由中配好,跳轉到Auth控制器中得getLogin方法)
建立一個登入視圖
在AuthController中建立一個登入視圖
php public function getLogin(){ return view("auth.login"); }
表單資料驗證
表單資料驗證在實現部分是postLogin方法中的 UserLoginRequest $req
我們建立一個請求類來對錶單進行資料驗證 使用laravel 提供的php artsian make:request 能非常輕鬆的建立一個請求類
php
class UserLoginRequest extends Request { /** * Determine if the user is authorized to make this request. * * @return bool */ public function authorize() { return true; } /** * Get the validation rules that apply to the request. * * @return array */ public function rules() { return [ //再這裡對錶單提交欄位進行過濾 'identity' => 'required|min:3|max:16', 'password' => 'required|min:6|max:16' ]; } public function sanitize() { return $this->all(); }}
登入處理方法
php public function postLogin(UserLoginRequest $req){ //這裡對傳遞過來得欄位進行了處理 這個函數為我自己定義的函數 僅僅是為了示範用 $identity = $this->generateLoginIdentity($req->input()); $identity['password'] = $req->input('password'); //驗證使用者帳號密碼 if($this->auth->attempt($indentity)){ //登入成功 記錄使用者登入時間和登入ip $user = User::where('id','=',$this->auth->user()->id)->first(); // 觸發一個事件 event(new \App\Events\UserLogin($user,$req->ip())); //重新導向到想要訪問的頁面 return redirect()->intended('/'); } }
如上述代碼所示 你可以對傳過來得資料根據業務需要做進一步的處理
驗證登入使用者功能的代碼是這一段$this->auth->attempt($indentity) 如果驗證成功回返回true,這個函數是laravel內建Auth的一個方法 功能是去User表中匹配傳過來的欄位,如果需要驗證更多欄位,當驗證成功後會將登入資訊存入session中。當然Auth去尋找匹配的表是可以更改的,我會在後面實現管理使用者的登入功能的時候示範怎麼修改。
然後可以在下面的代碼中繼續完成你的商務邏輯 如我代碼中所示的觸發一個事件來記錄登入事件和登入ip
已經登入 訪問登入頁面的自動跳轉
如果已經登入了 再訪問登入頁面 顯然我們不需要再出現登入視圖讓其登入,我們需要將其跳轉到其他路徑,這個路徑依然是可以修改的
首先我們看看再Auth控制器中哪裡對是否已經登入進行判斷
php public function __construct(Guard $auth, Registrar $registrar) { $this->auth = $auth; $this->registrar = $registrar; $this->middleware('guest', ['except' => 'getLogout']); }
其中這個except表示getLogout這個方法將不會受到這個中介軟體的影響 getLogout通常是登出方法
在這個控制器的構造方法調用了一個中介軟體來對是否已經登入進行判斷 ,通過尋找kernel.php我們找到這個中介軟體
是App\Http\Middleware\RedirectIfAuthenticated.php
php public function handle($request, Closure $next) { if ($this->auth->check()) { //跳轉的路徑 return new RedirectResponse(url('/')); } return $next($request); }
只要修改了上面代碼中跳轉的路徑就可以了
總結
我們可以看到 laravel已經給我們封裝了很多登入相關需要用到的功能 ,非常的完善,但也給了我們很大的自由隨意去修改登入相關的流程,我們可以隨意根據需要商務邏輯修改登入的功能。