Laravel核心代碼學習--用戶認證系統(基礎介紹)

用戶認證系統(基礎介紹)

使用過Laravel的開發者都知道,Laravel自帶了一個認證系統來提供基本的用戶註冊、登陸、認證、找回密碼,若是Auth系統裏提供的基礎功能不知足需求還能夠很方便的在這些基礎功能上進行擴展。這篇文章咱們先來了解一下Laravel Auth系統的核心組件。php

Auth系統的核心是由 Laravel 的認證組件的「看守器」和「提供器」組成。看守器定義了該如何認證每一個請求中用戶。例如,Laravel 自帶的 session 看守器會使用 session 存儲和 cookies 來維護狀態。git

下表列出了Laravel Auth系統的核心部件github

名稱 做用
Auth AuthManager的Facade
AuthManager Auth認證系統面向外部的接口,認證系統經過它嚮應用提供全部Auth用戶認證相關的方法,而認證方法的具體實現細節由它代理的具體看守器(Guard)來完成。
Guard 看守器,定義了該如何認證每一個請求中用戶
User Provider 用戶提供器,定義瞭如何從持久化的存儲數據中檢索用戶

在本文中咱們會詳細介紹這些核心部件,而後在文章的最後更新每一個部件的做用細節到上面給出的這個表中。web

開始使用Auth系統

只需在新的 Laravel 應用上運行 php artisan make:auth 和 php artisan migrate 命令就可以在項目裏生成Auth系統須要的路由和視圖以及數據表。數據庫

php artisan make:auth執行後會生成Auth認證系統須要的視圖文件,此外還會在路由文件web.php中增長響應的路由:api

Auth::routes();
複製代碼

Auth Facade文件中單獨定義了routes這個靜態方法bash

public static function routes()
{
    static::$app->make('router')->auth();
}
複製代碼

因此Auth具體的路由方法都定義在Illuminate\Routing\Routerauth方法中,關於如何找到Facade類代理的實際類能夠翻看以前Facade源碼分析的章節。cookie

namespace Illuminate\Routing;
class Router implements RegistrarContract, BindingRegistrar
{
    /**
     * Register the typical authentication routes for an application.
     *
     * @return void
     */
    public function auth()
    {
        // Authentication Routes...
        $this->get('login', 'Auth\LoginController@showLoginForm')->name('login');
        $this->post('login', 'Auth\LoginController@login');
        $this->post('logout', 'Auth\LoginController@logout')->name('logout');

        // Registration Routes...
        $this->get('register', 'Auth\RegisterController@showRegistrationForm')->name('register');
        $this->post('register', 'Auth\RegisterController@register');

        // Password Reset Routes...
        $this->get('password/reset', 'Auth\ForgotPasswordController@showLinkRequestForm')->name('password.request');
        $this->post('password/email', 'Auth\ForgotPasswordController@sendResetLinkEmail')->name('password.email');
        $this->get('password/reset/{token}', 'Auth\ResetPasswordController@showResetForm')->name('password.reset');
        $this->post('password/reset', 'Auth\ResetPasswordController@reset');
    }
}
複製代碼

auth方法裏能夠清晰的看到認證系統裏提供的全部功能的路由URI以及對應的控制器和方法。session

使用Laravel的認證系統,幾乎全部東西都已經爲你配置好了。其配置文件位於 config/auth.php,其中包含了用於調整認證服務行爲的註釋清晰的選項配置。app

<?php

return [

    /*
    |--------------------------------------------------------------------------
    | 認證的默認配置
    |--------------------------------------------------------------------------
    |
    | 設置了認證用的默認"看守器"和密碼重置的選項
    |
    */

    'defaults' => [
        'guard' => 'web',
        'passwords' => 'users',
    ],

    /*
    |--------------------------------------------------------------------------
    | Authentication Guards
    |--------------------------------------------------------------------------
    |
    | 定義項目使用的認證看守器,默認的看守器使用session驅動和Eloquent User 用戶數據提供者
    |
    | 全部的驅動都有一個用戶提供者,它定義瞭如何從數據庫或者應用使用的持久化用戶數據的存儲中取出用戶信息
    |
    | Supported: "session", "token"
    |
    */

    'guards' => [
        'web' => [
            'driver' => 'session',
            'provider' => 'users',
        ],

        'api' => [
            'driver' => 'token',
            'provider' => 'users',
        ],
    ],

    /*
    |--------------------------------------------------------------------------
    | User Providers
    |--------------------------------------------------------------------------
    |
    | 全部的驅動都有一個用戶提供者,它定義瞭如何從數據庫或者應用使用的持久化用戶數據的存儲中取出用戶信息
    |
    | Laravel支持經過不一樣的Guard來認證用戶,這裏能夠定義Guard的用戶數據提供者的細節:
    |        使用什麼driver以及對應的Model或者table是什麼
    |
    | Supported: "database", "eloquent"
    |
    */

    'providers' => [
        'users' => [
            'driver' => 'eloquent',
            'model' => App\Models\User::class,
        ],

        // 'users' => [
        //     'driver' => 'database',
        //     'table' => 'users',
        // ],
    ],

    /*
    |--------------------------------------------------------------------------
    | 重置密碼相關的配置
    |--------------------------------------------------------------------------
    |
    */

    'passwords' => [
        'users' => [
            'provider' => 'users',
            'table' => 'password_resets',
            'expire' => 60,
        ],
    ],

];
複製代碼

Auth系統的核心是由 Laravel 的認證組件的「看守器」和「提供器」組成。看守器定義了該如何認證每一個請求中用戶。例如,Laravel 自帶的 session 看守器會使用 session 存儲和 cookies 來維護狀態。

提供器中定義了該如何從持久化的存儲數據中檢索用戶。Laravel 自帶支持使用 Eloquent 和數據庫查詢構造器來檢索用戶。固然,你能夠根據須要自定義其餘提供器。

因此上面的配置文件的意思是Laravel認證系統默認使用了web guard配置項, 配置項裏使用的是看守器是SessionGuard,使用的用戶提供器是EloquentProvider 提供器使用的model是App\User

Guard

看守器定義了該如何認證每一個請求中用戶。Laravel自帶的認證系統默認使用自帶的 SessionGuardSessionGuard除了實現\Illuminate\Contracts\Auth契約裏的方法還實現Illuminate\Contracts\Auth\StatefulGuardIlluminate\Contracts\Auth\SupportsBasicAuth契約裏的方法,這些Guard Contracts裏定義的方法都是Laravel Auth系統默認認證方式依賴的基礎方法。

咱們先來看一下這一些基礎方法都意欲完成什麼操做,等到分析Laravel是如何經過SessionGuard認證用戶時在去關係這些方法的具體實現。

Illuminate\Contracts\Auth\Guard

這個文件定義了基礎的認證方法

namespace Illuminate\Contracts\Auth;

interface Guard
{
    /**
     * 返回當前用戶是否時已經過認證,是返回true,否者返回false
     *
     * @return bool
     */
    public function check();

    /**
     * 驗證是否時訪客用戶(非登陸認證經過的用戶)
     *
     * @return bool
     */
    public function guest();

    /**
     * 獲取當前用戶的用戶信息數據,獲取成功返回用戶User模型實例(\App\User實現了Authenticatable接口)
     * 失敗返回null
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public function user();

    /**
     * 獲取當前認證用戶的用戶ID,成功返回ID值,失敗返回null
     *
     * @return int|null
     */
    public function id();

    /**
     * 經過credentials(通常是郵箱和密碼)驗證用戶
     *
     * @param  array  $credentials
     * @return bool
     */
    public function validate(array $credentials = []);

    /**
     * 將一個\App\User實例設置成當前的認證用戶
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @return void
     */
    public function setUser(Authenticatable $user);
}

複製代碼

Illuminate\Contracts\Auth\StatefulGuard

這個Contracts定義了Laravel auth系統裏認證用戶時使用的方法,除了認證用戶外還會涉及用戶認證成功後如何持久化用戶的認證狀態。

<?php

namespace Illuminate\Contracts\Auth;

interface StatefulGuard extends Guard
{
    /**
     * Attempt to authenticate a user using the given credentials.
     * 經過給定用戶證書來嘗試認證用戶,若是remember爲true則在必定時間內記住登陸用戶
     * 認證經過後會設置Session和Cookies數據
     * @param  array  $credentials
     * @param  bool   $remember
     * @return bool
     */
    public function attempt(array $credentials = [], $remember = false);

    /**
     * 認證用戶,認證成功後不會設置session和cookies數據
     *
     * @param  array  $credentials
     * @return bool
     */
    public function once(array $credentials = []);

    /**
     * 登陸用戶(用戶認證成功後設置相應的session和cookies)
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @param  bool  $remember
     * @return void
     */
    public function login(Authenticatable $user, $remember = false);

    /**
     * 經過給定的用戶ID登陸用戶
     *
     * @param  mixed  $id
     * @param  bool   $remember
     * @return \Illuminate\Contracts\Auth\Authenticatable
     */
    public function loginUsingId($id, $remember = false);

    /**
     * 經過給定的用戶ID登陸用戶而且不設置session和cookies
     *
     * @param  mixed  $id
     * @return bool
     */
    public function onceUsingId($id);

    /**
     * Determine if the user was authenticated via "remember me" cookie.
     * 判斷用戶是否時經過name爲"remeber me"的cookie值認證的
     * @return bool
     */
    public function viaRemember();

    /**
     * 登出用戶
     *
     * @return void
     */
    public function logout();
}


複製代碼

Illuminate\Contracts\Auth\SupportsBasicAuth

定義了經過Http Basic Auth 認證用戶的方法

namespace Illuminate\Contracts\Auth;

interface SupportsBasicAuth
{
    /**
     * 嘗試經過HTTP Basic Auth來認證用戶
     *
     * @param  string  $field
     * @param  array  $extraConditions
     * @return \Symfony\Component\HttpFoundation\Response|null
     */
    public function basic($field = 'email', $extraConditions = []);

    /**
     * 進行無狀態的Http Basic Auth認證 (認證後不會設置session和cookies)
     *
     * @param  string  $field
     * @param  array  $extraConditions
     * @return \Symfony\Component\HttpFoundation\Response|null
     */
    public function onceBasic($field = 'email', $extraConditions = []);
}
複製代碼

User Provider

用戶提供器中定義了該如何從持久化的存儲數據中檢索用戶,Laravel定義了用戶提供器契約(interface),全部用戶提供器都要實現這個接口裏定義的抽象方法,由於實現了統一的接口因此使得不管是Laravel 自帶的仍是自定義的用戶提供器都可以被Guard使用。

用戶提供器契約

以下是契約中定義的必需被用戶提供器實現的抽象方法:

<?php

namespace Illuminate\Contracts\Auth;

interface UserProvider
{
    /**
     * 經過用戶惟一ID獲取用戶數據
     *
     * @param  mixed  $identifier
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public function retrieveById($identifier);

    /**
     * Retrieve a user by their unique identifier and "remember me" token.
     * 經過Cookies中的"remeber me"令牌和用戶惟一ID獲取用戶數據
     * @param  mixed   $identifier
     * @param  string  $token
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public function retrieveByToken($identifier, $token);

    /**
     * 更新數據存儲中給定用戶的remeber me令牌
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @param  string  $token
     * @return void
     */
    public function updateRememberToken(Authenticatable $user, $token);

    /**
     * 經過用戶證書獲取用戶信息
     *
     * @param  array  $credentials
     * @return \Illuminate\Contracts\Auth\Authenticatable|null
     */
    public function retrieveByCredentials(array $credentials);

    /**
     * 驗證用戶的證書
     *
     * @param  \Illuminate\Contracts\Auth\Authenticatable  $user
     * @param  array  $credentials
     * @return bool
     */
    public function validateCredentials(Authenticatable $user, array $credentials);
}
複製代碼

經過配置文件config/auth.php能夠看到Laravel默認使用的用戶提供器是Illuminate\Auth\EloquentUserProvider , 下一章節咱們分析Laravel Auth系統實現細節的時候咱們再來看看EloquentUserProvider是怎麼實現用戶提供器契約中的抽象方法的。

總結

本節咱們主要介紹Laravel Auth系統的基礎,包括Auth系統的核心組件看守器和提供器,AuthManager經過調用配置文件裏指定的看守器來完成用戶認證,在認證過程須要的用戶數據是看守器經過用戶提供器獲取到的,下面的表格裏總結了Auth系統的核心部件以及每一個部件的做用。

名稱 做用
Auth AuthManager的Facade
AuthManager Auth認證系統面向外部的接口,認證系統經過它嚮應用提供全部Auth用戶認證相關的方法,而認證方法的具體實現細節由它代理的具體看守器(Guard)來完成。
Guard 看守器,定義了該如何認證每一個請求中用戶,認證時須要的用戶數據會經過用戶數據提供器來獲取。
User Provider 用戶提供器,定義瞭如何從持久化的存儲數據中檢索用戶,Guard認證用戶時會經過提供器取用戶的數據,全部的提供器都是\Illuminate\Contracts\Auth\UserProvider接口的實現,提供了從持久化存儲中取用戶數據的具體實現細節。

下一章節咱們會看看Laravel自帶的用戶認證功能的實現細節。

本文已經收錄在系列文章Laravel源碼學習裏,歡迎訪問閱讀。

相關文章
相關標籤/搜索