laravel 的Auth類別有點疑問?

WBOY
發布: 2016-08-04 09:20:17
原創
1056 人瀏覽過

use Auth;

<code>use Illuminate\Routing\Controller;

class AuthController extends Controller {

    /**
     * Handle an authentication attempt.
     *
     * @return Response
     */
    public function authenticate()
    {
        if (Auth::attempt(['email' => $email, 'password' => $password]))
        {
            return redirect()->intended('dashboard');
        }
    }

}</code>
登入後複製
登入後複製

這個Auth門面它是怎麼驗證的呢?沒有資料庫查詢,沒有程式碼具體可以看​​啊。 。

回覆內容:

use Auth;

<code>use Illuminate\Routing\Controller;

class AuthController extends Controller {

    /**
     * Handle an authentication attempt.
     *
     * @return Response
     */
    public function authenticate()
    {
        if (Auth::attempt(['email' => $email, 'password' => $password]))
        {
            return redirect()->intended('dashboard');
        }
    }

}</code>
登入後複製
登入後複製

這個Auth門面它是怎麼驗證的呢?沒有資料庫查詢,沒有程式碼具體可以看​​啊。 。

Auth 類別是透過 class_alias 函數重新命名獲得的,原本是 IlluminateSupportFacadesAuth

不是很鼓勵 @granton 那種透過laravel ide helper 的方式查看,不利於學習(當然,這是一種技巧,只是不太適合正在學習的新人,倒是適合在專案開發中快速定位源,因為我就是這麼做的)。

繼續,如果真想要理解整個框架中類似這類的問題,就是順著框架走一遍,不但學得快,還能發現一些新大陸。這裡針對問題只提文件中所說的部分:服務提供者、服務容器、門面模式。

Facade 指門面模式,開頭我提了那個 Auth 的源頭,是一個 Facade,查看源代碼,實際發揮作用的就一行,你如果願意去看的話,實際上就是一個方法返回一個文本字符串。我建議你去閱讀文件關於服務提供者 的部分,那個地方是構建框架功能的核心,利用服務提供者在服務容器 註冊一個AuthManager 的供應者,在調用Facade 時,Facade 根據那個方法返回的字串會自動解析產生出AuthManager 實例(嚴格上講,AuthManager 是一個單例,透過其註冊的Provider 可查)。 AuthManager 提供了 Auth 這個 Facade 的所有功能,包括自動(根據配置)選擇驅動,由驅動提供給你這些如 attempt、login、check 這些方法。

如果你仔細閱讀完任何一個功能的文檔,尤其是 laravel 自身組件的,你都會發現他們支持擴展,擴展的方式也是利用服務容器,這是框架的核心。擴展你說的方法、改變加密方式非常簡單。

多讀文檔。

2016-07-27 補充:

只要明白這個框架的運作機制就很容易懂,實際上不複雜,大致如下(忽略不是很重要的細節,具體可以閱讀源碼):

  1. 建立 IlluminateFoundationApplication 實例;

  2. (適用於 Web 應用)建立 Http 核心實例 AppHttpKernel ---> IlluminateFoundationHttpKernel箭頭表示繼承關係

  3. 註冊服務提供者,並執行裡面的註冊行為,認證元件(IlluminateAuthAuthManager)就是在

    IlluminateAuthAuthServiceProvider
  4. 中被註冊,註冊完畢執行後續操作;
  5. 後續服務啟動,如中介軟體載入、路由分發、回應處理,至此完成流程。

上述流程中提到了一個 服務提供者(Service Provider),就是 IlluminateAuthAuthServiceProvider,可以看到在項目配置 config/app.php 中被註冊,裡面有一段重點:

<code>protected function registerAuthenticator()
{
    $this->app->singleton('auth', function ($app) {
        $app['auth.loaded'] = true;
        return new AuthManager($app);
    });

    $this->app->singleton('auth.driver', function ($app) {
        return $app['auth']->guard();
    });
}</code>
登入後複製

可以看到註冊了一個名為auth 的單例,是一個IlluminateAuthAuthManager 對象,我們所有透過Auth 類別存取的方法功能都由其提供,而Auth重新命名得到的類,實際上訪問Auth 就等於訪問IlluminateSupportFacadesAuthIlluminateSupportFacadesAuth 是一個Facade 的繼承,提供了​​一個方法,查看源代碼:

<code>class Auth extends Facade
{
    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor()
    {
        return 'auth';
    }
}</code>
登入後複製
注意到那個 return 'auth'; 沒,這個回傳值就是

Service Provider 中註冊的那個。為何 Facade 類別能夠擁有其指向的物件的方法?實際上是利用了魔術方法 __callStatic,可透過查看 IlluminateSupportFacadesFacade 原始碼得知。文檔也提到過。

至于你们去查看 AuthManager 并没发现一些可被执行的方法,实际上是因为 AuthManager 下还有一系列驱动(Driver),这些驱动使得 Auth 组件高度可定制化,文档上对这块做了着重讲解,驱动由两类构成,分别是实现了 Illuminate\Contracts\Auth\UserProvider 接口和 Illuminate\Contracts\Auth\Authenticatable 接口的类的实例,后者是用于提供认证组件获取认证对象信息的接口,比如获取账户、密码的方法,前者则是你们关注的,尤其是 retrieveByCredentialsvalidateCredentials 这两个接口方法,retrieveByCredentials 用于根据 attempt 传入的凭据获取用户实例的,validateCredentials 适用于验证凭据是否有效(想改变密码验证方式的就是通过该处实现)。

关于如何扩展、定制 Auth 组件,文档有说明,so~~~多读文档,这种问题读了文档,自然解决。不是简单看就完了,做到我说到任何一点你都知道在文档哪里去找,才说明你真的是读了文档的。我上面所提的所有,文档都写了。。。

以上。

如果使用 ide-helper, 可以在 _ide_helper.php 中看到这段代码

<code class="php">class Auth extends \Illuminate\Support\Facades\Auth{
    // ...
}</code>
登入後複製

其中

<code class="php">/**
 * Attempt to authenticate a user using the given credentials.
 *
 * @param array $credentials
 * @param bool $remember
 * @param bool $login
 * @return bool 
 * @static 
 */
public static function attempt($credentials = array(), $remember = false, $login = true){
    return \Illuminate\Auth\SessionGuard::attempt($credentials, $remember, $login);
}</code>
登入後複製

也就是说,这个 attempt 方法调用的是 \Illuminate\Auth\SessionGuard::attempt($credentials, $remember, $login) 方法。

具体的登陆验证的逻辑在里面。

config里的auth.php里配置了数据模型的吧,指定了model进行数据查询和匹配

相關標籤:
來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板