本文將深入探討Laravel框架的身份驗證系統,重點講解如何通過擴展核心身份驗證系統來創建自定義身份驗證守衛。
Laravel的核心提供了強大的身份驗證系統,輕鬆實現基本身份驗證。只需運行幾個artisan命令即可搭建身份驗證系統的腳手架。
此外,該系統的設計允許擴展並插入自定義身份驗證適配器。本文將詳細討論這一點。在深入講解自定義身份驗證守衛的實現之前,我們將先討論Laravel身份驗證系統中的基本元素——守衛和提供者。
Laravel身份驗證系統的核心由兩個元素組成——守衛和提供者。
可以將守衛理解為用於識別已認證用戶的邏輯提供者。 Laravel核心提供了不同的守衛,例如session和token。 session守衛通過cookie維護每個請求中的用戶狀態,而token守衛則通過檢查每個請求中的有效token來認證用戶。
因此,守衛定義了身份驗證的邏輯,並不一定總是通過從後端檢索有效憑據來實現。您可以實現一個守衛,它只需檢查請求頭中是否存在特定內容,並基於此內容認證用戶。
本文稍後將實現一個守衛,它檢查請求頭中某些JSON參數,並從MongoDB後端檢索有效用戶。
如果守衛定義了身份驗證的邏輯,那麼身份驗證提供者則負責從後端存儲中檢索用戶。如果守衛要求必須針對後端存儲驗證用戶,則檢索用戶的實現就包含在身份驗證提供者中。
Laravel自帶兩個默認身份驗證提供者——Database和Eloquent。 Database身份驗證提供者直接從後端存儲中檢索用戶憑據,而Eloquent則提供了一個抽象層來完成此操作。
在我們的示例中,我們將實現一個MongoDB身份驗證提供者,它從MongoDB後端獲取用戶憑據。
以上就是對Laravel身份驗證系統中守衛和提供者的基本介紹。從下一節開始,我們將重點介紹自定義身份驗證守衛和提供者的開發!
讓我們快速瀏覽一下本文中將要實現的文件列表。
如果文件列表目前還不清楚,不用擔心,我們將在講解過程中詳細討論每一個文件。
在本節中,我們將逐步講解所需文件的實現。
首先,我們需要讓Laravel知道我們的自定義守衛。請在config/auth.php文件中添加自定義守衛的詳細信息,如下所示。
<code>...<br>...<br>'guards' => [<br> 'web' => [<br> 'driver' => 'session',<br> 'provider' => 'users',<br> ],<br><br> 'api' => [<br> 'driver' => 'token',<br> 'provider' => 'users',<br> 'hash' => false,<br> ],<br><br> 'custom' => [<br> 'driver' => 'json',<br> 'provider' => 'mongo',<br> ],<br>],<br>...<br>...<br></code>
如您所見,我們在providers部分添加了我們的自定義守衛。
<code>...<br>...<br>'providers' => [<br> 'users' => [<br> 'driver' => 'eloquent',<br> 'model' => App\User::class,<br> ],<br> 'mongo' => [<br> 'driver' => 'mongo'<br> ],<br><br> // 'users' => [<br> // 'driver' => 'database',<br> // 'table' => 'users',<br> // ],<br>],<br>...<br>...<br></code>
我們在web中添加了我們的提供者條目到User模型。
根據身份驗證系統的標準,我們需要實現User模型。
如前所述,Laravel身份驗證系統由兩個元素組成——守衛和提供者。
在本節中,我們將創建一個身份驗證提供者,它負責從後端檢索用戶。
請創建文件app/Extensions/MongoUserProvider.php,內容如下。
<?php <br?>// app/Extensions/MongoUserProvider.php<br></br>namespace App\Extensions;<br></br><br></br>use Illuminate\Support\Str;<br></br>use Illuminate\Contracts\Auth\UserProvider;<br></br>use Illuminate\Contracts\Auth\Authenticatable;<br></br><br></br>class MongoUserProvider implements UserProvider<br></br>{<br></br> /**<br></br> * The Mongo User Model<br></br> */<br></br> private $model;<br></br><br></br> /**<br></br> * Create a new mongo user provider.<br></br> *<br></br> * @return \Illuminate\Contracts\Auth\Authenticatable|null<br></br> * @return void<br></br> */<br></br> public function __construct(\App\Models\Auth\User $userModel)<br></br> {<br></br> $this->model = $userModel;<br> }<br><br> /**<br> * Retrieve a user by the given credentials.<br> *<br> * @param array $credentials<br> * @return \Illuminate\Contracts\Auth\Authenticatable|null<br> */<br> public function retrieveByCredentials(array $credentials)<br> {<br> if (empty($credentials)) {<br> return;<br> }<br><br> $user = $this->model->fetchUserByCredentials(['username' => $credentials['username']]);<br><br> return $user;<br> }<br><br> /**<br> * Validate a user against the given credentials.<br> *<br> * @param \Illuminate\Contracts\Auth\Authenticatable $user<br> * @param array $credentials Request credentials<br> * @return bool<br> */<br> public function validateCredentials(Authenticatable $user, Array $credentials)<br> {<br> return ($credentials['username'] == $user->getAuthIdentifier() &&<br> md5($credentials['password']) == $user->getAuthPassword());<br> }<br><br> public function retrieveById($identifier) {}<br><br> public function retrieveByToken($identifier, $token) {}<br><br> public function updateRememberToken(Authenticatable $user, $token) {}<br>}<br>
同樣,您需要確保自定義提供者必須實現retrieveByCredentials
和前面討論過的User模型類。另一方面,jsondata
請求參數應該包含憑據的JSON編碼字符串。
在本節中,我們將創建一個守衛,它與上一節中創建的身份驗證提供者進行交互。
請創建文件app/Services/Auth/JsonGuard.php,內容如下。
<?php <br?>// app/Services/Auth/JsonGuard.php<br></br>namespace App\Services\Auth;<br></br><br></br>use Illuminate\Http\Request;<br></br>use Illuminate\Contracts\Auth\Guard;<br></br>use Illuminate\Contracts\Auth\UserProvider;<br></br>use GuzzleHttp\json_decode;<br></br>use phpDocumentor\Reflection\Types\Array_;<br></br>use Illuminate\Contracts\Auth\Authenticatable;<br></br><br></br>class JsonGuard implements Guard<br></br>{<br></br> protected $request;<br></br> protected $provider;<br></br> protected $user;<br></br><br></br> /**<br></br> * Create a new authentication guard.<br></br> *<br></br> * @param \Illuminate\Contracts\Auth\UserProvider $provider<br></br> * @param \Illuminate\Http\Request $request<br></br> * @return void<br></br> */<br></br> public function __construct(UserProvider $provider, Request $request)<br></br> {<br></br> $this->request = $request;<br> $this->provider = $provider;<br> $this->user = NULL;<br> }<br><br> /**<br> * Determine if the current user is authenticated.<br> *<br> * @return bool<br> */<br> public function check()<br> {<br> return ! is_null($this->user());<br> }<br><br> /**<br> * Determine if the current user is a guest.<br> *<br> * @return bool<br> */<br> public function guest()<br> {<br> return ! $this->check();<br> }<br><br> /**<br> * Get the currently authenticated user.<br> *<br> * @return \Illuminate\Contracts\Auth\Authenticatable|null<br> */<br> public function user()<br> {<br> if (! is_null($this->user)) {<br> return $this->user;<br> }<br> }<br><br> /**<br> * Get the JSON params from the current request<br> *<br> * @return string<br> */<br> public function getJsonParams()<br> {<br> $jsondata = $this->request->query('jsondata');<br><br> return (!empty($jsondata) ? json_decode($jsondata, TRUE) : NULL);<br> }<br><br> /**<br> * Get the ID for the currently authenticated user.<br> *<br> * @return string|null<br> */<br> public function id()<br> {<br> if ($user = $this->user()) {<br> return $this->user()->getAuthIdentifier();<br> }<br> }<br><br> /**<br> * Validate a user's credentials.<br> *<br> * @return bool<br> */<br> public function validate(Array $credentials=[])<br> {<br> if (empty($credentials['username']) || empty($credentials['password'])) {<br> if (!$credentials=$this->getJsonParams()) {<br> return false;<br> }<br> }<br><br> $user = $this->provider->retrieveByCredentials($credentials);<br><br> if (! is_null($user) && $this->provider->validateCredentials($user, $credentials)) {<br> $this->setUser($user);<br><br> return true;<br> } else {<br> return false;<br> }<br> }<br><br> /**<br> * Set the current user.<br> *<br> * @param Array $user User info<br> * @return void<br> */<br> public function setUser(Authenticatable $user)<br> {<br> $this->user = $user;<br> return $this;<br> }<br>}<br>
首先,我們的類需要實現mongo
。回想一下,密鑰反映了之前在CouchDB實現適配器中添加的設置。在這種情況下,他們只需要在登錄方法中添加相應的綁定,這需要實現未授權的消息。
另一方面,嘗試類似於http://your-laravel-site/custom/mongo/login?jsondata={"username":"admin","password":"admin"}
,如果用戶存在於您的數據庫中,則應該返回success
消息。
請注意,這只是一個示例,用於演示自定義守衛的工作方式。對於像登錄這樣的功能,您應該實現一個萬無一失的解決方案。事實上,我只是提供了對身份驗證流程的洞察;您負責為您的應用程序構建一個強大且安全的解決方案。
今天的旅程到此結束,希望我很快會帶來更多有用的內容。
Laravel框架在核心提供了強大的身份驗證系統,如果要實現自定義身份驗證系統,可以擴展它。這就是本文的主題:實現自定義守衛並將其插入到Laravel身份驗證工作流程中。
在此過程中,我們開發了一個基於請求中的JSON有效負載認證用戶並將其與MongoDB數據庫匹配的系統。為了實現這一點,我們最終創建了一個自定義守衛和一個自定義提供者實現。
我希望這個練習能讓您深入了解Laravel身份驗證流程,現在您應該對其內部工作原理更有信心了。
對於那些剛開始使用Laravel或希望通過擴展來擴展知識、網站或應用程序的人,Envato Market上有很多資源可供學習。
以上是如何在Laravel創建自定義身份驗證守護的詳細內容。更多資訊請關注PHP中文網其他相關文章!