权限控制是几乎每套成熟系统不可缺乏的一部分,咱们使用的权限控制方法是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已经给咱们封装了不少登陆相关须要用到的功能 ,很是的完善,但也给了咱们很大的自由随意去修改登陆相关的流程,咱们能够随意根据须要业务逻辑修改登陆的功能。