亚洲激情专区-91九色丨porny丨老师-久久久久久久女国产乱让韩-国产精品午夜小视频观看

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Laravel Auth原理的示例分析

發布時間:2021-03-12 10:32:31 來源:億速云 閱讀:287 作者:小新 欄目:編程語言

這篇文章給大家分享的是有關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;
    }

感謝各位的閱讀!關于“Laravel Auth原理的示例分析”這篇文章就分享到這里了,希望以上內容可以對大家有一定的幫助,讓大家可以學到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

通州市| 塘沽区| 福鼎市| 平阴县| 合水县| 阿克苏市| 阳泉市| 稷山县| 南华县| 容城县| 枞阳县| 马公市| 布尔津县| 连云港市| 即墨市| 德州市| 明溪县| 太和县| 磐安县| 苍南县| 讷河市| 阜新| 隆子县| 遂川县| 芷江| 荔浦县| 盘锦市| 沙田区| 高安市| 裕民县| 定兴县| 青阳县| 弥勒县| 湖南省| 绥江县| 陵川县| 靖西县| 唐海县| 平和县| 松滋市| 罗甸县|