In this article, we’re going to cover the authentication system in the Laravel framework. The main aim of this article is to create a custom authentication guard by extending the core authentication system.
Laravel provides a very solid authentication system in the core that makes the implementation of basic authentication a breeze. In fact, you just need to run a couple of artisan commands to set up the scaffolding of an authentication system.
Moreover, the system itself is designed in such a way that you could extend it and plug in your custom authentication adapters as well. That’s what we'll discuss in detail throughout this article. Before we go ahead and dive into the implementation of the custom authentication guard, we’ll start with a discussion of the basic elements in the Laravel authentication system—guards and providers.
The Laravel authentication system is made up of two elements at its core—guards and providers.
You could think of a guard as a way of supplying the logic that’s used to identify the authenticated users. In the core, Laravel provides different guards like session and token. The session guard maintains the state of the user in each request by cookies, and on the other hand the token guard authenticates the user by checking a valid token in every request.
So, as you can see, the guard defines the logic of authentication, and it’s not necessary that it always deals with that by retrieving valid credentials from the back end. You may implement a guard that simply checks the presence of a specific thing in request headers and authenticates users based on that.
Later in this article, we’ll implement a guard that checks certain JSON parameters in request headers and retrieves the valid user from the MongoDB back end.
If the guard defines the logic of authentication, the authentication provider is responsible for retrieving the user from the back-end storage. If the guard requires that the user must be validated against the back-end storage, then the implementation of retrieving the user goes into the authentication provider.
Laravel ships with two default authentication providers—Database and Eloquent. The Database authentication provider deals with the straightforward retrieval of the user credentials from the back-end storage, while Eloquent provides an abstraction layer that does the needful.
In our example, we’ll implement a MongoDB authentication provider that fetches the user credentials from the MongoDB back end.
So that was a basic introduction to guards and providers in the Laravel authentication system. From the next section onwards, we’ll focus on the development of the custom authentication guard and provider!
Let's have a quick look at the list of files that we'll implement throughout the course of this article.
Don't worry if the list of the files doesn't make much sense yet as we'll discuss everything in detail as we go through it.
In this section, we'll go through the implementation of the required files.
The first thing that we need to do is to inform Laravel about our custom guard. Go ahead and enter the custom guard details in the config/auth.php file as shown.
...
...
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
'hash' => false,
],
'custom' => [
'driver' => 'json',
'provider' => 'mongo',
],
],
...
...
As you can see, we've added our custom guard under the custom key.
Next, we need to add an associated provider entry in the providers section.
...
...
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
'mongo' => [
'driver' => 'mongo'
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
...
...
We've added our provider entry under the mongo key.
Finally, let's change the default authentication guard from web to custom.
...
...
'defaults' => [
'guard' => 'custom',
'passwords' => 'users',
],
...
...
Of course, it won't work yet, as we've not implemented the necessary files yet. And that's what we'll discuss in the next couple of sections.
In this section, we'll implement the necessary files that talk to the underlying MongoDB instance.
Let's first create the config/mongo.php configuration file, which holds the default MongoDB connection settings.
<?php
return [
'defaults' => [
'host' => '{HOST_IP}',
'port' => '{HOST_PORT}',
'database' => '{DB_NAME}'
]
];
Of course, you need to change the placeholder values as per your settings.
Instead of directly creating a class that interacts with MongoDB, we'll create an interface in the first place.
The benefit of creating an interface is that it provides a contract that a developer must adhere to while implementing it. Also, our implementation of MongoDB could be easily swapped with another NoSQL implementation if needed.
Go ahead and create the app/Services/Contracts/NosqlServiceInterface.php interface file with the following contents.
<?php
// app/Services/Contracts/NosqlServiceInterface.php
namespace App\Services\Contracts;
Interface NosqlServiceInterface
{
/**
* Create a Document
*
* @param string $collection Collection/Table Name
* @param array $document Document
* @return boolean
*/
public function create($collection, Array $document);
/**
* Update a Document
*
* @param string $collection Collection/Table Name
* @param mix $id Primary Id
* @param array $document Document
* @return boolean
*/
public function update($collection, $id, Array $document);
/**
* Delete a Document
*
* @param string $collection Collection/Table Name
* @param mix $id Primary Id
* @return boolean
*/
public function delete($collection, $id);
/**
* Search Document(s)
*
* @param string $collection Collection/Table Name
* @param array $criteria Key-value criteria
* @return array
*/
public function find($collection, Array $criteria);
}
It's a pretty simple interface which declares the basic CRUD methods that a class must define that implements this interface.
Now, let's define the app/Database/MongoDatabase.php class with the following contents.
<?php
// app/Database/MongoDatabase.php
namespace App\Database;
use App\Services\Contracts\NosqlServiceInterface;
class MongoDatabase implements NosqlServiceInterface
{
private $manager;
private $database;
public function __construct($host, $port, $database)
{
$this->database = $database;
$this->manager = new \MongoDB\Driver\Manager( "mongodb://".$host.":".$port."/".$database );
}
/**
* @see \App\Services\Contracts\NosqlServiceInterface::find()
*/
public function find($collection, Array $criteria)
{
$query = new \MongoDB\Driver\Query($criteria);
$result = $this->manager->executeQuery($this->database.".".$collection, $query);
$user = array();
foreach ($result as $row) {
$user['username'] = $row->username;
$user['password'] = $row->password;
}
return $user;
}
public function create($collection, Array $document) {}
public function update($collection, $id, Array $document) {}
public function delete($collection, $id) {}
}
Of course, I assume that you've installed MongoDB and the corresponding MongoDB PHP extension.
The __construct method instantiates the MongoClient class with the necessary parameters. The other important method we're interested in is the find method, which retrieves the record based on the criteria provided as method arguments.
So that was the implementation of the MongoDB driver, and I tried to keep it as simple as possible.
User ModelAdhering to the standards of the authentication system, we need to implement the User model, which must implement the Illuminate\Contracts\Auth\Authenticatable contract.
Go ahead and create a file app/Models/Auth/User.php with the following contents.
<?php
// app/Models/Auth/User.php
namespace App\Models\Auth;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use App\Services\Contracts\NosqlServiceInterface;
class User implements AuthenticatableContract
{
private $conn;
private $username;
private $password;
protected $rememberTokenName = 'remember_token';
public function __construct(NosqlServiceInterface $conn)
{
$this->conn = $conn;
}
/**
* Fetch user by Credentials
*
* @param array $credentials
* @return Illuminate\Contracts\Auth\Authenticatable
*/
public function fetchUserByCredentials(Array $credentials)
{
$arr_user = $this->conn->find('users', ['username' => $credentials['username']]);
if (! is_null($arr_user)) {
$this->username = $arr_user['username'];
$this->password = $arr_user['password'];
}
return $this;
}
/**
* {@inheritDoc}
* @see \Illuminate\Contracts\Auth\Authenticatable::getAuthIdentifierName()
*/
public function getAuthIdentifierName()
{
return "username";
}
/**
* {@inheritDoc}
* @see \Illuminate\Contracts\Auth\Authenticatable::getAuthIdentifier()
*/
public function getAuthIdentifier()
{
return $this->{$this->getAuthIdentifierName()};
}
/**
* {@inheritDoc}
* @see \Illuminate\Contracts\Auth\Authenticatable::getAuthPassword()
*/
public function getAuthPassword()
{
return $this->password;
}
/**
* {@inheritDoc}
* @see \Illuminate\Contracts\Auth\Authenticatable::getRememberToken()
*/
public function getRememberToken()
{
if (! empty($this->getRememberTokenName())) {
return $this->{$this->getRememberTokenName()};
}
}
/**
* {@inheritDoc}
* @see \Illuminate\Contracts\Auth\Authenticatable::setRememberToken()
*/
public function setRememberToken($value)
{
if (! empty($this->getRememberTokenName())) {
$this->{$this->getRememberTokenName()} = $value;
}
}
/**
* {@inheritDoc}
* @see \Illuminate\Contracts\Auth\Authenticatable::getRememberTokenName()
*/
public function getRememberTokenName()
{
return $this->rememberTokenName;
}
}
You should have already noticed that App\Models\Auth\User implements the Illuminate\Contracts\Auth\Authenticatable contract.
Most of the methods implemented in our class are self-explanatory. Having said that, we've defined the fetchUserByCredentials method, which retrieves the user from the available back end. In our case, it'll be a MongoDatabase class which will be called to retrieve the necessary information.
So that's the implementation of the User model.
As we discussed earlier, the Laravel authentication system consists of two elements—guards and providers.
In this section, we'll create an authentication provider, which deals with the user retrieval from the back end.
Go ahead and create a file app/Extensions/MongoUserProvider.php as shown below.
<?php
// app/Extensions/MongoUserProvider.php
namespace App\Extensions;
use Illuminate\Support\Str;
use Illuminate\Contracts\Auth\UserProvider;
use Illuminate\Contracts\Auth\Authenticatable;
class MongoUserProvider implements UserProvider
{
/**
* The Mongo User Model
*/
private $model;
/**
* Create a new mongo user provider.
*
* @return \Illuminate\Contracts\Auth\Authenticatable|null
* @return void
*/
public function __construct(\App\Models\Auth\User $userModel)
{
$this->model = $userModel;
}
/**
* Retrieve a user by the given credentials.
*
* @param array $credentials
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function retrieveByCredentials(array $credentials)
{
if (empty($credentials)) {
return;
}
$user = $this->model->fetchUserByCredentials(['username' => $credentials['username']]);
return $user;
}
/**
* Validate a user against the given credentials.
*
* @param \Illuminate\Contracts\Auth\Authenticatable $user
* @param array $credentials Request credentials
* @return bool
*/
public function validateCredentials(Authenticatable $user, Array $credentials)
{
return ($credentials['username'] == $user->getAuthIdentifier() &&
md5($credentials['password']) == $user->getAuthPassword());
}
public function retrieveById($identifier) {}
public function retrieveByToken($identifier, $token) {}
public function updateRememberToken(Authenticatable $user, $token) {}
}
Again, you need to make sure that the custom provider must implement the Illuminate\Contracts\Auth\UserProvider contract.
Moving ahead, it defines two important methods—retrieveByCredentials and validateCredentials.
The retrieveByCredentials method is used to retrieve the user credentials using the User model class which was discussed in the earlier section. On the other hand, the validateCredentials method is used to validate a user against the given set of credentials.
And that was the implementation of our custom authentication provider. In the next section, we'll go ahead and create a guard which interacts with the MongoUserProvider authentication provider.
As we discussed earlier, the guard in the Laravel authentication system provisions how a user is authenticated. In our case, we'll check the presence of the jsondata request parameter which should contain the JSON-encoded string of the credentials.
In this section, we'll create a guard which interacts with the authentication provider which was just created in the last section.
Go ahead and create a file app/Services/Auth/JsonGuard.php with the following contents.
<?php
// app/Services/Auth/JsonGuard.php
namespace App\Services\Auth;
use Illuminate\Http\Request;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Contracts\Auth\UserProvider;
use GuzzleHttp\json_decode;
use phpDocumentor\Reflection\Types\Array_;
use Illuminate\Contracts\Auth\Authenticatable;
class JsonGuard implements Guard
{
protected $request;
protected $provider;
protected $user;
/**
* Create a new authentication guard.
*
* @param \Illuminate\Contracts\Auth\UserProvider $provider
* @param \Illuminate\Http\Request $request
* @return void
*/
public function __construct(UserProvider $provider, Request $request)
{
$this->request = $request;
$this->provider = $provider;
$this->user = NULL;
}
/**
* Determine if the current user is authenticated.
*
* @return bool
*/
public function check()
{
return ! is_null($this->user());
}
/**
* Determine if the current user is a guest.
*
* @return bool
*/
public function guest()
{
return ! $this->check();
}
/**
* Get the currently authenticated user.
*
* @return \Illuminate\Contracts\Auth\Authenticatable|null
*/
public function user()
{
if (! is_null($this->user)) {
return $this->user;
}
}
/**
* Get the JSON params from the current request
*
* @return string
*/
public function getJsonParams()
{
$jsondata = $this->request->query('jsondata');
return (!empty($jsondata) ? json_decode($jsondata, TRUE) : NULL);
}
/**
* Get the ID for the currently authenticated user.
*
* @return string|null
*/
public function id()
{
if ($user = $this->user()) {
return $this->user()->getAuthIdentifier();
}
}
/**
* Validate a user's credentials.
*
* @return bool
*/
public function validate(Array $credentials=[])
{
if (empty($credentials['username']) || empty($credentials['password'])) {
if (!$credentials=$this->getJsonParams()) {
return false;
}
}
$user = $this->provider->retrieveByCredentials($credentials);
if (! is_null($user) && $this->provider->validateCredentials($user, $credentials)) {
$this->setUser($user);
return true;
} else {
return false;
}
}
/**
* Set the current user.
*
* @param Array $user User info
* @return void
*/
public function setUser(Authenticatable $user)
{
$this->user = $user;
return $this;
}
}
First of all, our class needs to implement the Illuminate\Contracts\Auth\Guard interface. Thus, we need to define all the methods declared in that interface.
The important thing to note here is that the __construct function requires an implementation of Illuminate\Contracts\Auth\UserProvider. In our case, we'll pass an instance of App\Extensions\MongoUserProvider, as we'll see in the later section.
Next, there's a function getJsonParams that retrieves the user credentials from the request parameter named jsondata. As it's expected that we'll receive a JSON encoded string of the user credentials, we've used the json_decode function to decode the JSON data.
In the validate function, the first thing we check is the existence of the $credentials argument. If it's not present, we'll call the getJsonParams method to retrieve user credentials from the request parameters.
Next, we call the retrieveByCredentials method of the MongoUserProvider provider that retrieves the user from the MongoDB database back end. Finally, it's the validateCredentials method of the MongoUserProvider provider that checks the validity of the user.
So that was the implementation of our custom guard. The next section describes how to stitch these pieces together to form a successful authentication system.
So far, we've developed all the elements of the custom authentication guard that should provide us with a new authentication system. However, it won't work out of the box as we need to register it in the first place using the Laravel service container bindings.
As you should already know, the Laravel service provider is the right place to implement the necessary bindings.
Go ahead and open the file app/Providers/AuthServiceProvider.php which allows us to add authentication service container bindings. If it doesn't contain any custom changes, you could just replace it with the following contents.
<?php
// app/Providers/AuthServiceProvider.php
namespace App\Providers;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Gate;
use Illuminate\Foundation\Support\Providers\AuthServiceProvider as ServiceProvider;
use App\Services\Auth\JsonGuard;
use App\Extensions\MongoUserProvider;
use App\Database\MongoDatabase;
use App\Models\Auth\User;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Config;
class AuthServiceProvider extends ServiceProvider
{
/**
* The policy mappings for the application.
*
* @var array
*/
protected $policies = [
'App\Model' => 'App\Policies\ModelPolicy',
];
/**
* Register any authentication / authorization services.
*
* @return void
*/
public function boot()
{
$this->registerPolicies();
$this->app->bind('App\Database\MongoDatabase', function ($app) {
return new MongoDatabase(config('mongo.defaults.host'), config('mongo.defaults.port'), config('mongo.defaults.database'));
});
$this->app->bind('App\Models\Auth\User', function ($app) {
return new User($app->make('App\Database\MongoDatabase'));
});
// add custom guard provider
Auth::provider('mongo', function ($app, array $config) {
return new MongoUserProvider($app->make('App\Models\Auth\User'));
});
// add custom guard
Auth::extend('json', function ($app, $name, array $config) {
return new JsonGuard(Auth::createUserProvider($config['provider']), $app->make('request'));
});
}
public function register()
{
$this->app->bind(
'App\Services\Contracts\NosqlServiceInterface',
'App\Database\MongoDatabase'
);
}
}
Let's go through the boot method which contains most of the provider bindings.
To start with, we'll create bindings for the App\Database\MongoDatabase and App\Models\Auth\User elements.
$this->app->bind('App\Database\MongoDatabase', function ($app) {
return new MongoDatabase(config('mongo.defaults.host'), config('mongo.defaults.port'), config('mongo.defaults.database'));
});
$this->app->bind('App\Models\Auth\User', function ($app) {
return new User($app->make('App\Database\MongoDatabase'));
});
We've been talking about providers and guards for a while, and it's time to plug our custom guard into the Laravel authentication system.
We've used the provider method of the Auth Facade to add our custom authentication provider under the key mongo. Recall that the key reflects the settings that were added earlier in the auth.php file.
Auth::provider('mongo', function ($app, array $config) {
return new MongoUserProvider($app->make('App\Models\Auth\User'));
});
In a similar way, we'll inject our custom guard implementation using the extend method of the Auth facade.
Auth::extend('json', function ($app, $name, array $config) {
return new JsonGuard(Auth::createUserProvider($config['provider']), $app->make('request'));
});
Next, there's the register method which we've used to bind the App\Services\Contracts\NosqlServiceInterface interface to the App\Database\MongoDatabase implementation.
$this->app->bind( 'App\Services\Contracts\NosqlServiceInterface', 'App\Database\MongoDatabase' );
So whenever there's a need to resolve the App\Services\Contracts\NosqlServiceInterface dependency, Laravel responds with the implementation of the App\Database\MongoDatabase adapter.
The benefit of using this approach is that one could easily swap the given implementation with a custom implementation. For example, let's say someone would like to replace the App\Database\MongoDatabase implementation with the CouchDB implementation adapter in future. In that case, they just need to add the corresponding binding in the register method.
So that was the service provider at your disposal. At this moment, we have everything which is required to test our custom guard implementation, so the next and concluding section is all about that.
You've done all the hard work setting up your first custom authentication guard, and now it's time to reap the benefits as we'll go ahead and give it a try.
Let's quickly implement the app/Http/Controllers/MongoController.php controller as shown below.
<?php
// app/Http/Controllers/MongoController.php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use Illuminate\Contracts\Auth\Guard;
class MongoController extends Controller
{
public function login(Guard $auth_guard)
{
if ($auth_guard->validate()) {
// get the current authenticated user
$user = $auth_guard->user();
echo 'Success!';
} else {
echo 'Not authorized to access this page!';
}
}
}
Take a close look at the dependency of the login method, which requires the implementation of the Illuminate\Contracts\Auth\Guard guard. Since we've set the custom guard as the default guard in the auth.php file, it's the App\Services\Auth\JsonGuard that'll be injected actually!
Next, we've called the validate method of the App\Services\Auth\JsonGuard class, which in turn initiates a series of method calls:
retrieveByCredentials method of the App\Extensions\MongoUserProvider class.retrieveByCredentials method calls the fetchUserByCredentials method of the App\Models\Auth\User class.fetchUserByCredentials method calls the find method of the App\Database\MongoDatabase to retrieve the user credentials.find method of the App\Database\MongoDatabase returns the response!If everything works as expected, we should get the authenticated user by calling the user method of our guard.
To access the controller, you should add an associated route in the routes/web.php file.
Route::get('/custom/mongo/login', 'MongoController@login');
Try accessing the URL https://your-laravel-site/custom/mongo/login without passing any parameters and you should see the not authorized message.
On the other hand, try something like http://your-laravel-site/custom/mongo/login?jsondata={"username":"admin","password":"admin"} and that should return the success message if the user is present in your database.
Please note that this is just for example purposes to demonstrate how a custom guard works. You should implement a foolproof solution for a feature like a login. In fact, I've just provided an insight into the authentication flow; you're responsible for building a robust and secure solution for your application.
That ends our journey today, and hopefully I'll be back with more useful stuff.
The Laravel framework provides a solid authentication system in the core that could be extended if you want to implement a custom one. That was the topic of today's article: to implement a custom guard and plug it in to the Laravel authentication workflow.
In the course of that, we went ahead and developed a system that authenticates the user based on the JSON payload in the request and matches it with the MongoDB database. And to achieve that, we ended up creating a custom guard and a custom provider implementation.
I hope the exercise has given you an insight into the Laravel authentication flow, and you should now feel more confident about its inner workings.
For those of you who are either just getting started with Laravel or looking to expand your knowledge, site, or application with extensions, we have a variety of things you can study on Envato Market.
The Best Small Business Web Designs by DesignRush
/
2Create Modern Vue Apps Using Create-Vue and Vite
/
7Pros and Cons of Using WordPress
/
-5How to Fix the “There Has Been a Critical Error in Your Website” Error in WordPress
How To Fix The “There Has Been A Critical Error in Your Website” Error in WordPress
How to Create a Privacy Policy Page in WordPress
/
9WordPress Website Maintenance Guide For Beginners
/
7How Long Does It Take to Learn JavaScript?
/
-1How Long Does it Take to Learn JavaScript
/
1The Best Way to Deep Copy an Object in JavaScript
/
-3
4
-5Adding and Removing Elements From Arrays in JavaScript
/
-2Create a JavaScript AJAX Post Request: With and Without jQuery
/
85 Real-Life Uses for the JavaScript reduce() Method
/
-9How to Enable or Disable a Button With [removed] jQuery vs. Vanilla
/
2How to Enable or Disable a Button With [removed] jQuery vs Vanilla
/
-3Confirm Yes or No With JavaScript
/
-3How to Change the URL in [removed] Redirecting
/
-315+ Best WordPress Twitter Widgets
/
-227 Best Tab and Accordion Widget Plugins for WordPress (Free & Premium)
/
1121 Best Tab and Accordion Widget Plugins for WordPress (Free & Premium)
/
-1130 HTML Best Practices for Beginners
/
-831 Best WordPress Calendar Plugins and Widgets (With 5 Free Plugins)
/
525 Ridiculously Impressive HTML5 Canvas Experiments
/
-3
1How to Implement Email Verification for New Members
/
3How to Create a Simple Web-Based Chat Application
/
730 Popular WordPress User Interface Elements
/
-4Top 18 Best Practices for Writing Super Readable Code
/
3Best Affiliate WooCommerce Plugins Compared
/
-1018 Best WordPress Star Rating Plugins
/
1510+ Best WordPress Twitter Widgets
/
320+ Best WordPress Booking and Reservation Plugins
/
4Working With Tables in React: Part Two
/
-3Best CSS Animations and Effects on CodeCanyon
/
-1630 CSS Best Practices for Beginners
/
3How to Create a Custom WordPress Plugin From Scratch
/
310 Best Responsive HTML5 Sliders for Images and Text… and 3 Free Options
/
-516 Best Tab and Accordion Widget Plugins for WordPress
/
-518 Best WordPress Membership Plugins and 5 Free Plugins
/
525 Best WooCommerce Plugins for Products, Pricing, Payments and More
/
210 Best WordPress Twitter Widgets
1 /
1412 Best Contact Form PHP Scripts for 2020
/
-320 Popular WordPress User Interface Elements
/
-310 Best WordPress Star Rating Plugins
/
-312 Best CSS Animations on CodeCanyon
/
-112 Best WordPress Booking and Reservation Plugins
/
120 Best WordPress Calendar Plugins and Widgets
/
-212 Elegant CSS Pricing Tables for Your Latest Web Project
/
924 Best WordPress Form Plugins for 2020
/
-214 Best PHP Event Calendar and Booking Scripts
/
-1Getting Started With Django: Newly Updated Course
/
-1Create a Blog for Each Category or Department in Your WooCommerce Store
/
28 Best WordPress Booking and Reservation Plugins
/
-16Best Exit Popups for WordPress Compared
/
19Best Exit Popups for WordPress Compared
/
-411 Best Tab & Accordion WordPress Widgets & Plugins
/
-1112 Best Tab & Accordion WordPress Widgets & Plugins
1 /
3New Course: Practical React Fundamentals
/
2Short Course: Better Angular App Architecture With Modules
/
3Preview Our New Course on Angular Material
/
6Build Your Own CAPTCHA and Contact Form in PHP
/
-1Object-Oriented PHP With Classes and Objects
/
2Best Practices for ARIA Implementation
/
-4Accessible Apps: Barriers to Access and Getting Started With Accessibility
/
-3Dramatically Speed Up Your React Front-End App Using Lazy Loading
/
1915 Best Modern JavaScript Admin Templates for React, Angular, and Vue.js
/
-1515 Best Modern JavaScript Admin Templates for React, Angular and Vue.js
/
219 Best JavaScript Admin Templates for React, Angular, and Vue.js
/
3New Course: Build an App With JavaScript and the MEAN Stack
/
11Hands-on With ARIA: Accessibility Recipes for Web Apps
/
810 Best WordPress Facebook Widgets
13Hands-on With ARIA: Accessibility for eCommerce
/
6New eBooks Available for Subscribers
/
-8Hands-on With ARIA: Homepage Elements and Standard Navigation
/
10
-7Site Accessibility: Getting Started With ARIA
/
4How Secure Are Your JavaScript Open-Source Dependencies?
/
-3New Course: Secure Your WordPress Site With SSL
/
-3Testing Components in React Using Jest and Enzyme
/
-9Testing Components in React Using Jest: The Basics
/
-515 Best PHP Event Calendar and Booking Scripts
/
-2Create Interactive Gradient Animations Using Granim.js
/
10How to Build Complex, Large-Scale Vue.js Apps With Vuex
1Examples of Dependency Injection in PHP With Symfony Components
/
-5Set Up Routing in PHP Applications Using the Symfony Routing Component
1 /
9A Beginner’s Guide to Regular Expressions in JavaScript
/
10Introduction to Popmotion: Custom Animation Scrubber
/
-5Introduction to Popmotion: Pointers and Physics
/
-10New Course: Connect to a Database With Laravel’s Eloquent ORM
/
-5How to Create a Custom Settings Panel in WooCommerce
/
-14Building the DOM faster: speculative parsing, async, defer and preload
1 /
220 Useful PHP Scripts Available on CodeCanyon
3 /
50How to Find and Fix Poor Page Load Times With Raygun
/
1Introduction to the Stimulus Framework
/
-11Single-Page React Applications With the React-Router and React-Transition-Group Modules
/
1
712 Best Contact Form PHP Scripts
1 /
-4Getting Started With the Mojs Animation Library: The ShapeSwirl and Stagger Modules
/
1Getting Started With the Mojs Animation Library: The Shape Module
/
-3Getting Started With the Mojs Animation Library: The HTML Module
/
4Project Management Considerations for Your WordPress Project
/
-78 Things That Make Jest the Best React Testing Framework
/
3Creating an Image Editor Using CamanJS: Layers, Blend Modes, and Events
/
-1New Short Course: Code a Front-End App With GraphQL and React
/
2Creating an Image Editor Using CamanJS: Applying Basic Filters
/
-13Creating an Image Editor Using CamanJS: Creating Custom Filters and Blend Modes
/
-1Challenge: Create a To-Do List in React
1 /
-1Deploy PHP Web Applications Using Laravel Forge
/
-2Getting Started With the Mojs Animation Library: The Burst Module
/
5
-1010 Things Men Can Do to Support Women in Tech
/
-3A Gentle Introduction to Higher-Order Components in React: Best Practices
/
-5Challenge: Build a React Component
/
-4A Gentle Introduction to HOC in React: Learn by Example
/
3A Gentle Introduction to Higher-Order Components in React
/
-6Creating Pretty Popup Messages Using SweetAlert2
/
5Creating Stylish and Responsive Progress Bars Using ProgressBar.js
/
1818 Best Contact Form PHP Scripts for 2022
/
-2How to Make a Real-Time Sports Application Using Node.js
/
-2Creating a Blogging App Using Angular & MongoDB: Delete Post
/
-15Creating a Blogging App Using Angular & MongoDB: Edit Post
/
-1Introduction to Mocking in Python
/
-1Creating a Blogging App Using Angular & MongoDB: Show Post
/
8Creating a Blogging App Using Angular & MongoDB: Home
/
8
3Creating a Blogging App Using Angular & MongoDB: Login
/
13Creating Your First Angular App: Implement Routing
/
13Persisted WordPress Admin Notices: Part 4
/
-3Creating Your First Angular App: Components, Part 2
/
4Persisted WordPress Admin Notices: Part 3
/
4
9Persisted WordPress Admin Notices: Part 2
/
-2Create Your First Angular App: Storing and Accessing Data
/
3Persisted WordPress Admin Notices: Part 1
/
-2Error and Performance Monitoring for Web & Mobile Apps Using Raygun
/
6Using Luxon for Date and Time in JavaScript
7 /
-7How to Create an Audio Oscillator With the Web Audio API
/
-4How to Cache Using Redis in Django Applications
/
220 Essential WordPress Utilities to Manage Your Site
/
-6Introduction to API Calls With React and Axios
/
16Beginner’s Guide to Angular 4: HTTP
/
12Rapid Web Deployment for Laravel With GitHub, Linode, and RunCloud.io
/
9Beginners Guide to Angular 4: Routing
/
-8Beginner’s Guide to Angular 4: Components
/
3Creating a Drop-Down Menu for Mobile Pages
/
6Introduction to Forms in Angular 4: Writing Custom Form Validators
/
410 Best WordPress Booking & Reservation Plugins
/
1Getting Started With Redux: Connecting Redux With React
/
15Getting Started With Redux: Learn by Example
/
15Getting Started With Redux: Why Redux?
/
9Understanding Recursion With JavaScript
/
-2How to Auto Update WordPress Salts
/
-4How to Download Files in Python
/
-3
-21Eloquent Mutators and Accessors in Laravel
1 /
16
-11
1210 Best HTML5 Sliders for Images and Text
/
7Site Authentication in Node.js: User Signup
/
-3Creating a Task Manager App Using Ionic: Part 2
/
3Creating a Task Manager App Using Ionic: Part 1
/
2Introduction to Forms in Angular 4: Reactive Forms
/
1
4Introduction to Forms in Angular 4: Template-Driven Forms
/
224 Essential WordPress Utilities to Manage Your Site
/
-225 Essential WordPress Utilities to Manage Your Site
/
-11Get Rid of Bugs Quickly Using BugReplay
1 /
-14Manipulating HTML5 Canvas Using Konva: Part 1, Getting Started
/
510 Must-See Easy Digital Downloads Extensions for Your WordPress Site
/
-222 Best WordPress Booking and Reservation Plugins
/
-4Understanding ExpressJS Routing
/
-715 Best WordPress Star Rating Plugins
/
12Creating Your First Angular App: Basics
/
-1Inheritance and Extending Objects With JavaScript
/
-10Introduction to the CSS Grid Layout With Examples
1 /
3
6Performant Animations Using KUTE.js: Part 5, Easing Functions and Attributes
/
-9Performant Animations Using KUTE.js: Part 4, Animating Text
/
-13Performant Animations Using KUTE.js: Part 3, Animating SVG
/
-8New Course: Code a Quiz App With Vue.js
/
-1Performant Animations Using KUTE.js: Part 2, Animating CSS Properties
/
3
9Performant Animations Using KUTE.js: Part 1, Getting Started
/
110 Best Responsive HTML5 Sliders for Images and Text (Plus 3 Free Options)
/
-3Single-Page Applications With ngRoute and ngAnimate in AngularJS
/
-13Deferring Tasks in Laravel Using Queues
/
-5
3Site Authentication in Node.js: User Signup and Login
/
11Working With Tables in React, Part Two
/
-17Working With Tables in React, Part One
/
4How to Set Up a Scalable, E-Commerce-Ready WordPress Site Using ClusterCS
/
-4New Course on WordPress Conditional Tags
/
3TypeScript for Beginners, Part 5: Generics
/
1
-14Building With Vue.js 2 and Firebase
6 /
14
-8
-1Best Unique Bootstrap JavaScript Plugins
/
-8
-2Essential JavaScript Libraries and Frameworks You Should Know About
/
7
1Vue.js Crash Course: Create a Simple Blog Using Vue.js
/
-13Build a React App With a Laravel RESTful Back End: Part 1, Laravel 5.5 API
/
6API Authentication With Node.js
/
-4Beginner’s Guide to Angular: HTTP
/
7Beginner’s Guide to Angular: Routing
/
-4Beginners Guide to Angular: Routing
/
-4Beginner’s Guide to Angular: Services
/
3How to Create a Custom Authentication Guard in Laravel
/
6Learn Computer Science With [removed] Part 3, Loops
/
-5Build Web Applications Using Node.js
/
1Learn Computer Science With [removed] Part 4, Functions
/
3Learn Computer Science With [removed] Part 2, Conditionals
/
12Learn Computer Science With [removed] Part 1, The Basics
/
-3Create Interactive Charts Using Plotly.js, Part 5: Pie and Gauge Charts
/
-9Create Interactive Charts Using Plotly.js, Part 4: Bubble and Dot Charts
/
16Create Interactive Charts Using Plotly.js, Part 3: Bar Charts
/
-13Awesome JavaScript Libraries and Frameworks You Should Know About
/
-4Create Interactive Charts Using Plotly.js, Part 2: Line Charts
/
-8Bulk Import a CSV File Into MongoDB Using Mongoose With Node.js
/
-6Build a To-Do API With Node, Express, and MongoDB
/
-7Getting Started With End-to-End Testing in Angular Using Protractor
/
10TypeScript for Beginners, Part 4: Classes
/
-16Object-Oriented Programming With JavaScript
/
510 Best Affiliate WooCommerce Plugins Compared
/
7Stateful vs. Stateless Functional Components in React
/
9Make Your JavaScript Code Robust With Flow
/
-3Build a To-Do API With Node and Restify
/
8Testing Components in Angular Using Jasmine: Part 2, Services
/
2Testing Components in Angular Using Jasmine: Part 1
/
-2Creating a Blogging App Using React, Part 6: Tags
/
-9React Crash Course for Beginners, Part 3
/
3React Crash Course for Beginners, Part 2
/
9React Crash Course for Beginners, Part 1
/
3Set Up a React Environment, Part 4
1 /
9Set Up a React Environment, Part 3
/
-11New Course: Get Started With Phoenix
/
-9Set Up a React Environment, Part 2
/
2Command Line Basics and Useful Tricks With the Terminal
/
4How to Create a Real-Time Feed Using Phoenix and React
/
-4Build a React App With a Laravel Back End: Part 2, React
/
3Build a React App With a Laravel RESTful Back End: Part 1, Laravel 9 API
/
-5Creating a Blogging App Using React, Part 5: Profile Page
/
-1Pagination in CodeIgniter: The Complete Guide
/
21JavaScript-Based Animations Using Anime.js, Part 4: Callbacks, Easings, and SVG
JavaScript-Based Animations Using Anime.js, Part 3: Values, Timeline, and Playback
Learn to Code With [removed] Part 1, The Basics
/
410 Elegant CSS Pricing Tables for Your Latest Web Project
/
-8Getting Started With the Flux Architecture in React
/
-3Getting Started With Matter.js: The Composites and Composite Modules
/
2Getting Started With Matter.js: The Engine and World Modules
/
1610 More Popular HTML5 Projects for You to Use and Study
/
-23Understand the Basics of Laravel Middleware
/
-3Iterating Fast With Django & Heroku
/
8Creating a Blogging App Using React, Part 4: Update & Delete Posts
/
4Creating a jQuery Plugin for Long Shadow Design
/
-11How to Register & Use Laravel Service Providers
2 /
-13Unit Testing in React: Shallow vs. Static Testing
/
5Creating a Blogging App Using React, Part 3: Add & Display Post
/
15Creating a Blogging App Using React, Part 2: User Sign-Up
20 /
-4Creating a Blogging App Using React, Part 1: User Sign-In
/
89 More Popular HTML5 Projects for You to Use and Study
/
17Creating a Grocery List Manager Using Angular, Part 2: Managing Items
/
89 Elegant CSS Pricing Tables for Your Latest Web Project
/
-1Dynamic Page Templates in WordPress, Part 3
/
-2Angular vs. React: 7 Key Features Compared
/
6Creating a Grocery List Manager Using Angular, Part 1: Add & Display Items
/
2New eBooks Available for Subscribers in June 2017
/
6Create Interactive Charts Using Plotly.js, Part 1: Getting Started
/
10The 5 Best IDEs for WordPress Development (And Why)
/
-133 Popular WordPress User Interface Elements
/
2New Course: How to Hack Your Own App
/
-10How to Install Yii on Windows or a Mac
/
3What Is a JavaScript Operator?
/
-6How to Register and Use Laravel Service Providers
/
7
waly Good blog post. I absolutely love this…