本文将深入探讨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中文网其他相关文章!