关于Laravel Auth原理浅析

关于Laravel Auth原理浅析,第1张

概述关于Laravel Auth原理浅析 下面由Laravel教程栏目给大家介绍Laravel Auth原理浅析,希望对需要的朋友有所帮助!

由于公司最近使用Laravel-admin做后台,接触了下Laravel框架,不得不说,Laravel社区的力量以及生态确实挺强大。

  但是公司内部业务都处于Java端,后台全部都是调JavaAPI,因此使用Laravel的特性就得大打折扣了,首先Eloquent模型完全不能用,我这边把业务分开来,只存了3张表,这是Laravel-admin自带的表。

  Laravel-admin带了9张表,由于用户登录业务全保存在API端,自带的表功能被我割舍了。因此需要自己实现API登录的逻辑,而又必须走Laravel Auth认证。

原理解读

// 使用下面这个命令Laravel会自动为我们生成Auth路由和认证模块。跟着代码往下解读。  PHP artisan make:auth   // http/Controllers/Auth/LoginController 使用了 AuthenticatesUsers

其中 下面这三个方法诠释了登录逻辑的全部。

public function login(Request $request)    {        $this->valIDateLogin($request);        if ($this->hasTooManyLoginAttempts($request)) {            $this->fireLockoutEvent($request);            return $this->sendLockoutResponse($request);        }        // 这里尝试登录系统,        if ($this->attemptLogin($request)) {            return $this->sendLoginResponse($request);        }        $this->incrementLoginAttempts($request);        return $this->sendFailedLoginResponse($request);    }    protected function attemptLogin(Request $request)    {        return $this->guard()->attempt(            $this->credentials($request), $request->has('remember')        );    }    protected function guard()    {        return Auth::guard();    }

控制器会去寻找Auth::guard(), 那这个Auth::guard()是个什么东西呢,

首先 Auth 是系统的单例,原型在

Illuminate\Auth\AuthManager;

顾名思义,是一个Auth管理模块,实现了认证工厂模式接口guards(),

public function __construct($app)    {        $this->app = $app;        $this->userResolver = function ($guard = null) {            return $this->guard($guard)->user();        };    }    // Auth::guard();就是调用了这个方法。    public function guard($name = null)    {        // 首先查找$name, 没有就使用默认的驱动,        $name = $name ?: $this->getDefaultDriver();        // 意思就是要实例化出这个驱动并且返回,        return isset($this->guards[$name])                    ? $this->guards[$name]                    : $this->guards[$name] = $this->resolve($name);    }       // 默认的驱动是从配置文件里面读取的,/config/auth.PHP default配置项    public function getDefaultDriver()    {        return $this->app['config']['auth.defaults.guard'];    }     // 这里是构造Auth-guard驱动   protected function resolve($name)    {        $config = $this->getConfig($name);        if (is_null($config)) {            throw new invalidargumentexception("xxx");        }        // 这里是如果你自己实现的驱动就返回        if (isset($this->customCreators[$config['driver']])) {            return $this->callCustomCreator($name, $config);        }        // 这里是系统默认两个类分别是        // session 和 token 这里主要讲 sessionGuard .        $driverMethod = 'create'.ucfirst($config['driver']).'Driver';        if (method_exists($this, $driverMethod)) {            return $this->{$driverMethod}($name, $config);        }        throw new invalidargumentexception("xxx");    }

接下来看看配置文件 auth.PHP

 // Auth::guard() ,不传参数,就调用默认的default.guard ,   'defaults' => [        'guard' => 'web',        'passwords' => 'users',    ],   // 系统的guard .默认支持 "database", "eloquent",意思就是说你的provIDer必须是这两个实例中的一个,    'guards' => [        'web' => [            'driver' => 'session',            'provIDer' => 'users',        ],        'API' => [            'driver' => 'token',            'provIDer' => 'users',        ],    ],  // 这个就是上面的provIDer了,你使用哪一个provIDer作为你的Auth::guard()返回的 // 模型    'provIDers' => [        'users' => [            'driver' => 'eloquent',            'model' => App\User::class,        ],        // 'users' => [        //     'driver' => 'database',        //     'table' => 'users',        // ],    ],

也就是说终归到底,Auth::guard(), 在默认配置里面是给我反回了一个sessionGuard .

主要看下面4个方法

namespace Illuminate\Auth;class SessionGuard{    public function attempt(array $credentials = [], $remember = false)    {        // 这里触发 试图登录事件,此时还没有登录        $this->fireAttemptEvent($credentials, $remember);        $this->lastAttempted =         $user = $this->provIDer->retrIEveByCredentials($credentials);        // 这里会调用hasValIDCredentials,其实就是验证用户名和密码的一个过程        if ($this->hasValIDCredentials($user, $credentials)) {            // 如果验证通过了,就调用login方法 .            $this->login($user, $remember);            return true;        }        // 否则就触发登录失败事件,返回假        $this->fireFailedEvent($user, $credentials);        return false;    }    // 这里是登录用户的 *** 作,就是说调用这个方法已经是合法用户了,必须是一个  // AuthenticatableContract 的实例 .    public function login(AuthenticatableContract $user,     $remember = false)    {        // 直接更新session,这里就是把session存起来,session的键在该方法的        // getname() 里边,        $this->updateSession($user->getAuthIDentifIEr());        if ($remember) {            $this->ensureRememberTokenIsSet($user);            $this->queueRecallercookie($user);        }     // 触发登录事件,已经登录了这个时候,        $this->fireLoginEvent($user, $remember);        // 将user对象保存到sessionGuard , 后续的类访问Auth::user();直接拿到        $this->setUser($user);    }    // 这里就是经常使用到的 Auth::user()了,具体如何返回看AuthManager里面的    // __call    public function user()    {        if ($this->loggedOut) {            return;        }        if (! is_null($this->user)) {            return $this->user;        }        // 这里读取session拿到user的ID ,        $ID = $this->session->get($this->getname());        $user = null;        // 如果拿到了ID ,查找到该user        if (! is_null($ID)) {            if ($user = $this->provIDer->retrIEveByID($ID)) {                $this->fireAuthenticatedEvent($user);            }        }        $recaller = $this->recaller();        if (is_null($user) && ! is_null($recaller)) {            $user = $this->userFromrecaller($recaller);            if ($user) {                $this->updateSession($user->getAuthIDentifIEr());                $this->fireLoginEvent($user, true);            }        }        return $this->user = $user;    }    // 这里就直接返回用户ID了,    public function ID()    {        if ($this->loggedOut) {            return;        }        return $this->user()                    ? $this->user()->getAuthIDentifIEr()                    : $this->session->get($this->getname());    }}

大体上用户登录的流程就完了,简单过程就是

//伪代码$credentials = $request()->only(['username' ,'password']);if(Auth::guard("session")->attempt($credentials)){  // 登录成功}else{  // 登录失败}

实现用户登录之后才能访问的控制器/方法

Route::get("/home")->mIDdleware("auth");// auth MIDdleware 是在app/http/Kernel中注册的,// 类名是  \Illuminate\Auth\MIDdleware\Authenticate::class// 解析过程实质上是这个方法:    public function handle($request, Closure $next, ...$guards)    {        $this->authenticate($guards);        return $next($request);    }      protected function authenticate(array $guards)    {          // 默认情况下会去 Auth中寻找authenticate这个方法        if (empty($guards)) {            return $this->auth->authenticate();        }        // 如果mIDdleware中传了参数,会遍历一遍,不通过就抛出异常        foreach ($guards as $guard) {            if ($this->auth->guard($guard)->check()) {                return $this->auth->shouldUse($guard);            }        }        throw new AuthenticationException('Unauthenticated.', $guards);    }    //sessionGuard 中的authenticate其实也就是调用了一遍user方法。    public function authenticate()    {        if (! is_null($user = $this->user())) {            return $user;        }        throw new AuthenticationException;    }

第一次写文,有错误请指出谢谢! 总结

以上是内存溢出为你收集整理的关于Laravel Auth原理浅析全部内容,希望文章能够帮你解决关于Laravel Auth原理浅析所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://www.outofmemory.cn/langs/1227917.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存