Laravel框架之auth权限流程分析

7个月前 0 0 2239

Laravel框架之auth权限流程分析!为了记录一下,以防以后能更好的使用auth权限!

都知道这是官方内置的登录注册,该怎么更好的使用它呢?如果你看官方文档的话,说实话根本无法扩展这个auth,只能自己慢慢解析他的源码,更好了解其流程,这样才能更好的使用,说实话,现在任何一款框架的文档都不可能让你随心所欲使用框架,只要去了解源码这条路,才能更好的掌握!

跟着文档安装好auth之后(具体操作文档已经说得很清楚了,这个就不做具体说明了)

首先看路由,使用laravel的首要第一就是看路由,在你artisan之后,你会在路由文件里面看到这个!

Route::auth();
Route::get('/home', 'HomeController@index');

猛然一看,每个人第一次学习这个框架看到这个肯定都是一脸懵(当然大神除外),如果你仔细研读过文档的facades(门面这一节了),看到Route::静态调用就能想到这是用的门面获取的,既然了解是通过门面来获取的,那就好办了,首先到IlluminateSupportFacadesRoute文件返回的是"router',这样的话对照门面表找到其对应的类IlluminateRoutingRouter,找到这个Router文件看看,嘿嘿,找到了不是

public function auth()
    {
        // Authentication Routes...
        $this->get('login', 'AuthAuthController@showLoginForm');
        $this->post('login', 'AuthAuthController@login');
        $this->get('logout', 'AuthAuthController@logout');

        // Registration Routes...
        $this->get('register', 'AuthAuthController@showRegistrationForm',function(){
            return view('auth.login');
        });
        $this->post('register', 'AuthAuthController@register',function(){
            return view('auth.login');
        });

        // Password Reset Routes...
        $this->get('password/reset/{token?}', 'AuthPasswordController@showResetForm',function(){
            return view('auth.login');
        });
        $this->post('password/email', 'AuthPasswordController@sendResetLinkEmail',function(){
            return view('auth.login');
        });
        $this->post('password/reset', 'AuthPasswordController@reset',function(){
            return view('auth.login');
        });
    }

到这里看到auth权限的所有路由了!可以仔细看看,也是一路了然,就不对每个路由作解释了!

找到第一个login,看完AuthAuthController@showLoginForm,原来登录界面在AuthAuthController的showLoginForm方法!走,去看看这个AuthAuthController文件。???是不是到里面一看什么都没有,只有validator和create方法,很奇怪啊,路由命名就是指向这个控制器的showLoginForm方法啊,怎么会没有呢?难道是继承了吗?看一下,我靠,继承的controller,不用想肯定不是这个,再往下看一下,发现两个奇怪的东西

use AuthenticatesAndRegistersUsers, ThrottlesLogins;

难道是这两个吗?追踪进去看看trait AuthenticatesAndRegistersUsers,就两行代码,又是use!

use AuthenticatesUsers, RegistersUsers {
        AuthenticatesUsers::redirectPath insteadof RegistersUsers;
        AuthenticatesUsers::getGuard insteadof RegistersUsers;
    }

是不是发现了RegisterUsers很明显了注册,那么另外一个肯定就是登录的啦,追进去看一下是不是!

public function showLoginForm()
    {
        $view = property_exists($this, 'loginView')
                    ? $this->loginView : 'auth.authenticate';
        
        if (view()->exists($view)) {
            return view($view);
        }
        
        return view('auth.login');
    }

果然就有,那么就是这个,看一下代码,这段代码的解释就是你可以自定义自己的login页面!在AuthController添加这个属性就可以了

protected $loginView = '';//你的login'地址
自定义页面解决!

来看看提交,对了,因为我是首先看的login,如果你需要register,但是整个过程应该和login差不多,可以试着去看一下.

来看看提交的路由AuthController@login
找一下login方法,第一行就是$this->validateLogin($request);验证login 方法,来看看validateLogin()方法
protected function validateLogin(Request $request)
{
        $this->validate($request, [
            $this->loginUsername() => 'required', 'password' => 'required',
        ]);
}//这个就是登录验证两个必须字段
 public function loginUsername()
    {
        return property_exists($this, 'username') ? $this->username : 'email';
    }//看看这个方法,就是你可以修改登录是email还是username了!当然跟loginview一样你需要加上这个username这个属性
再往下就是这个

 $throttles = $this->isUsingThrottlesLoginsTrait();//是否已经使用ThrottlesLogins::class
看一下isUsingThrottlesLoginsTrait()

protected function isUsingThrottlesLoginsTrait()
    {
        return in_array(
            ThrottlesLogins::class, class_uses_recursive(static::class)
        );
    }//主要就是class_uses_recursive()这个laravel内置方法,获取当前类以及他父类的所有使用的trait!
很明显返回是true,ThrottlesLogins在AuthController使用过!再往下看
if ($throttles && $lockedOut = $this->hasTooManyLoginAttempts($request)) {
            $this->fireLockoutEvent($request);

            return $this->sendLockoutResponse($request);
        }
看一下if条件的这个判读语句$lockedOut = $this->hasTooManyLoginAttempts($request)这个方法IDE追踪不到,那说明不在所在控制器或者父类中,那就在trait当中,你可以到几个trait当中查看,你会在ThrottlesLogins中发现这个方法!
protected function hasTooManyLoginAttempts(Request $request)
    {
        return app(RateLimiter::class)->tooManyAttempts(
            $this->getThrottleKey($request),//获取你的用户名和ip组合xxxx|127.0.0.1作为键值
            $this->maxLoginAttempts(), //获取用户最大的尝试登陆次数,看这个方法你会发现默认次数是五次,你可以设置"maxLoginAttempts"这个属性来改变
            $this->lockoutTime() / 60//这个应该就是尝试失败之间间隔,默认是60秒,可以通过"lockoutTime"属性来设置
        );
    }
来看看tooManyAttempts方法,返回bool值
public function tooManyAttempts($key, $maxAttempts, $decayMinutes = 1)
    {
        if ($this->cache->has($key.':lockout')) {//当前用户是否被锁定?
            return true;
        }
        //如果当前用户尝试的次数大于最大的尝试次数,则锁定该用户,并且重置
        if ($this->attempts($key) > $maxAttempts) {
            $this->cache->add($key.':lockout', time() + ($decayMinutes * 60), $decayMinutes);

            $this->resetAttempts($key);

            return true;
        }

        return false;
    }
以现在的话我是违背锁定的,所以进步了这个if判断,假设是true的话,进去看看,这个if判断的两个方法做了什么

 $this->fireLockoutEvent($request);//用户被锁定诉
 return $this->sendLockoutResponse($request);//返回报错信息Too many login attempts. Please try again in  xxx秒
继续往下走:

$credentials = $this->getCredentials($request);//获取用户名和密码
下面就是如何通过guard!
Auth::guard($this->getGuard())返回的就是SessionGuardhttp://www.njphper.com/detail/106.html

到IlluminateAuthSessionGuard文件里面找到attempt()方法,看一下这个方法
public function attempt(array $credentials = [], $remember = false, $login = true)
    {
        $this->fireAttemptEvent($credentials, $remember, $login);

        $this->lastAttempted = $user = $this->provider->retrieveByCredentials($credentials);//查询登录的用户并返回User模型

        if ($this->hasValidCredentials($user, $credentials)) {//再次确认密码加密后是否正确
            if ($login) {
                $this->login($user, $remember);//存储到session:设置id(user表的id),设置remmbertoken,存储user信息等
            }
            return true;
        }

        if ($login) {
            $this->fireFailedEvent($user, $credentials);
        }

        return false;
    }
以上就是auth登录的全部过程

版权声明:自由转载-非商用-非衍生-保持署名(创意共享3.0许可证)

评论 (0)

    暂无评论~

njphper@copyright From 2014 to 2019-02-17