權限控制是幾乎每套成熟系統不可缺乏的一部分,咱們使用的權限控制方法是rbac,我將在這個系列的文章一步步完成一個比較複雜的rbac權限控制。php
rbac權限控制是一個很是成熟的權限控制系統,其原理是給每一個用戶一個或多個角色 而每一個角色對系統相應模塊有訪問權限,具體理論知識很少介紹。在我完成這個權限控制系統中,我將普通用戶和管理員用戶分開在數據庫中存儲,咱們先完成普通用戶的登陸,這一部分相對於管理員用戶會比較簡單,同時也讓你們理解下登陸的流程。laravel
當咱們訪問某些必定要登陸後才能使用的功能時 咱們每每會有一個功能就是 若是沒有登陸的用戶,就會直接跳轉到登陸功能 在laravel已經提供的代碼中咱們能夠很是輕鬆完成這個功能ajax
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中註冊數組
phpprotected $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的中間件session
找到App\Http\Middleware\Authenticateapp
phppublic 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方法)ide
在AuthController中創建一個登陸視圖函數
phppublic function getLogin(){ return view("auth.login"); }
表單數據驗證在實現部分是postLogin方法中的 UserLoginRequest $req
咱們創建一個請求類來對錶單進行數據驗證 使用laravel 提供的php artsian make:request 能很是輕鬆的創建一個請求類post
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(); } }
phppublic 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控制器中哪裏對是否已經登陸進行判斷
phppublic 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
phppublic function handle($request, Closure $next) { if ($this->auth->check()) { //跳轉的路徑 return new RedirectResponse(url('/')); } return $next($request); }
只要修改了上面代碼中跳轉的路徑就能夠了
咱們能夠看到 laravel已經給咱們封裝了不少登陸相關須要用到的功能 ,很是的完善,但也給了咱們很大的自由隨意去修改登陸相關的流程,咱們能夠隨意根據須要業務邏輯修改登陸的功能。