关于Laravel Auth原理浅析

2022-05-15 0 468

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

关于Laravel Auth原理浅析

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

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

关于Laravel Auth原理浅析

  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;    }

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

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

【声明:根据2013年1月30日《计算机软件保护条例》2次修订第17条规定: 为了学习和研究软件内含的设计思想和原理,通过安装、显示、传输或者存 储软件等方式使用软件的,可以不经软件著作权人许可,不向其支付报酬! 鉴于此,也希望大家按此说明研究软件!】
本站所有源码尽量保证原汁原味,如有特殊情况会作出声明及标注,网站资源不做任何二次加密(原版加密除外,不影响程序使用的不会做解密处理),方便您更好的学习参考。 在您的能力范围内,为了大环境的良性发展,请尽可能的选择正版资源。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

即刻码站__国内靠谱的站长资源下载平台 php教程 关于Laravel Auth原理浅析 https://www.jike1995.com/36772.html

常见问题
  • 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用
查看详情
  • 最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度
查看详情

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务