How to Create a Custom Authentication Guard in Laravel
This article will explore the authentication system of the Laravel framework in depth, focusing on how to create a custom authentication guard by extending the core authentication system.
Laravel's core provides a powerful authentication system that allows basic authentication to be easily implemented. Just run a few artisan commands to build the scaffolding of the authentication system.
In addition, the system is designed to allow extension and insertion of custom authentication adapters. This article will discuss this in detail. Before we dive into the implementation of custom authentication guards, we will first discuss the basic elements of the Laravel authentication system - guards and providers.
Core elements: Guard and Provider
The core of the Laravel authentication system is composed of two elements - the guard and the provider.
Guard
Guards can be understood as logical providers used to identify authenticated users. The Laravel core provides different guards such as session and token. The session guard maintains the user status in each request through cookies, while the token guard authenticates the user by checking the valid token in each request.
Therefore, the guard defines the logic of authentication and is not always implemented by retrieving valid credentials from the backend. You can implement a guard that simply checks for specific content in the request header and authenticates the user based on this content.
A guard will be implemented later in this article, which checks for certain JSON parameters in the request header and retrieves valid users from the MongoDB backend.
Provider
If the guard defines the logic for authentication, the authentication provider is responsible for retrieving users from the backend storage. If the guard requires that the user must be authenticated against the backend storage, the implementation of the search user is included in the authentication provider.
Laravel comes with two default authentication providers - Database and Eloquent. Database authentication providers retrieve user credentials directly from backend storage, while Eloquent provides an abstraction layer to do this.
In our example, we will implement a MongoDB authentication provider that fetches user credentials from the MongoDB backend.
The above is a basic introduction to the guards and providers in the Laravel authentication system. Starting from the next section, we will focus on the development of custom authentication guards and providers!
File settings overview
Let's take a quick look at the list of files to be implemented in this article.
- config/auth.php: This is the authentication configuration file where we will add the entry for the custom guard.
- config/mongo.php: File containing MongoDB configuration.
- app/Services/Contracts/NosqlServiceInterface.php: Interface implemented by our custom Mongo database class.
- app/Database/MongoDatabase.php: The main database class that interacts with MongoDB.
- app/Models/Auth/User.php: User model class that implements the Authenticable contract.
- app/Extensions/MongoUserProvider.php: Implementation of authentication providers.
- app/Services/Auth/JsonGuard.php: Implementation of the authentication guard driver.
- app/Providers/AuthServiceProvider.php: We will use to add existing files bound to the service container.
- app/Http/Controllers/MongoController.php: The demo controller file we will implement to test custom guards.
If the file list is not clear at the moment, don't worry, we will discuss each file in detail during the explanation.
In-depth implementation
In this section, we will gradually explain the implementation of the required files.
First of all, we need to let Laravel know about our custom guards. Please add the details of the custom guard in the config/auth.php file as shown below.
<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>
As you can see, we have added our custom guard in the providers section.
<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>
We added our provider entry to the User model in the web.
According to the standards of the authentication system, we need to implement the User model.
Set the authentication provider
As mentioned earlier, the Laravel authentication system consists of two elements - the guard and the provider.
In this section, we will create an authentication provider that is responsible for retrieving users from the backend.
Please create the file app/Extensions/MongoUserProvider.php, the content is as follows.
<?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>
Similarly, you need to make sure that the custom provider must implement retrieveByCredentials
and the User model class discussed earlier. On the other hand, the jsondata
request parameter should contain the JSON-encoded string of the credentials.
In this section, we will create a guard that interacts with the authentication provider created in the previous section.
Please create the file app/Services/Auth/JsonGuard.php, the content is as follows.
<?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>
First, our class needs to implement mongo
. Recall that the key reflects the settings that were previously added in the CouchDB implementation adapter. In this case, they just need to add the corresponding binding in the login method, which requires implementing unauthorized messages.
On the other hand, try something similar to http://your-laravel-site/custom/mongo/login?jsondata={"username":"admin","password":"admin"}
, if the user exists in your database, you should return a success
message.
Note that this is just an example to demonstrate how custom guards work. For features like login, you should implement a foolproof solution. In fact, I just provide insight into the authentication process; you are responsible for building a powerful and secure solution for your application.
Today's journey ends here, and hopefully I will bring more useful content soon.
Conclusion
Laravel framework provides a powerful authentication system in the core, and can be extended if you want to implement a custom authentication system. This is the topic of this article: Implementing custom guards and inserting them into the Laravel authentication workflow.
In this process, we developed a system that authenticates users based on the requested JSON payload and matches them with the MongoDB database. To achieve this we ended up creating a custom guard and a custom provider implementation.
I hope this exercise will give you an in-depth understanding of the Laravel authentication process, and now you should be more confident in how it works internally.
For those who are just starting out with Laravel or want to extend their knowledge, websites, or applications through extensions, there are a lot of resources available on Envato Market to learn.
The above is the detailed content of How to Create a Custom Authentication Guard in Laravel. For more information, please follow other related articles on the PHP Chinese website!

Hot AI Tools

Undresser.AI Undress
AI-powered app for creating realistic nude photos

AI Clothes Remover
Online AI tool for removing clothes from photos.

Undress AI Tool
Undress images for free

Clothoff.io
AI clothes remover

AI Hentai Generator
Generate AI Hentai for free.

Hot Article

Hot Tools

Notepad++7.3.1
Easy-to-use and free code editor

SublimeText3 Chinese version
Chinese version, very easy to use

Zend Studio 13.0.1
Powerful PHP integrated development environment

Dreamweaver CS6
Visual web development tools

SublimeText3 Mac version
God-level code editing software (SublimeText3)

Hot Topics



Laravel simplifies handling temporary session data using its intuitive flash methods. This is perfect for displaying brief messages, alerts, or notifications within your application. Data persists only for the subsequent request by default: $request-

The PHP Client URL (cURL) extension is a powerful tool for developers, enabling seamless interaction with remote servers and REST APIs. By leveraging libcurl, a well-respected multi-protocol file transfer library, PHP cURL facilitates efficient execution of various network protocols, including HTTP, HTTPS, and FTP. This extension offers granular control over HTTP requests, supports multiple concurrent operations, and provides built-in security features.

Laravel provides concise HTTP response simulation syntax, simplifying HTTP interaction testing. This approach significantly reduces code redundancy while making your test simulation more intuitive. The basic implementation provides a variety of response type shortcuts: use Illuminate\Support\Facades\Http; Http::fake([ 'google.com' => 'Hello World', 'github.com' => ['foo' => 'bar'], 'forge.laravel.com' =>

PHP logging is essential for monitoring and debugging web applications, as well as capturing critical events, errors, and runtime behavior. It provides valuable insights into system performance, helps identify issues, and supports faster troubleshoot

Do you want to provide real-time, instant solutions to your customers' most pressing problems? Live chat lets you have real-time conversations with customers and resolve their problems instantly. It allows you to provide faster service to your custom

Article discusses late static binding (LSB) in PHP, introduced in PHP 5.3, allowing runtime resolution of static method calls for more flexible inheritance.Main issue: LSB vs. traditional polymorphism; LSB's practical applications and potential perfo

The article discusses adding custom functionality to frameworks, focusing on understanding architecture, identifying extension points, and best practices for integration and debugging.

Alipay PHP...
