Extending Laravel's Authentication: Creating Custom Guards

Extending Laravel's Authentication: Creating Custom Guards

Laravel's authentication system is robust and flexible out of the box, but sometimes your application might require a specialised authentication method. This is where custom authentication guards come into play. Let's explore how to create and implement a custom guard in Laravel.

Understanding Custom Guards

Custom guards allow you to define your own authentication logic, which can be particularly useful for implementing JWT authentication, OAuth, or any other specialized auth system that doesn't fit into Laravel's default guard types.

Creating a Custom Guard

To create a custom guard, you'll need to use the Auth::extend() method. This is typically done in a service provider. Let's walk through the process:

  1. Create Your Guard Class

First, create a new class that implements the Illuminate\Contracts\Auth\Guard interface. For this example, we'll create a simple JWT guard:

namespace App\Services\Auth;

use Illuminate\Contracts\Auth\Guard;

class JwtGuard implements Guard
{
    protected $provider;
    protected $user;

    public function __construct($provider)
    {
        $this->provider = $provider;
    }

    public function check()
    {
        // Check if the user is authenticated
    }

    public function user()
    {
        // Return the authenticated user
    }

    // Implement other methods required by the Guard interface
}
  1. Register the Custom Guard

In your AppServiceProvider or a dedicated AuthServiceProvider, register your custom guard:

namespace App\Providers;

use App\Services\Auth\JwtGuard;
use Illuminate\Support\Facades\Auth;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Auth::extend('jwt', function ($app, $name, array $config) {
            return new JwtGuard(Auth::createUserProvider($config['provider']));
        });
    }
}
  1. Configure the Guard

In your config/auth.php file, add your new guard:

'guards' => [
    'web' => [
        'driver' => 'session',
        'provider' => 'users',
    ],
    'api' => [
        'driver' => 'jwt',
        'provider' => 'users',
    ],
],

Implementing the Guard Logic

In your guard class, you'll need to implement the authentication logic. Here's a basic example of what the check() and user() methods might look like in a JWT guard:

public function check()
{
    if (! $this->user) {
        $token = $this->getTokenFromRequest();
        
        if ($token && $this->validateToken($token)) {
            $this->user = $this->provider->retrieveById($this->getPayload($token)->sub);
        }
    }

    return $this->user !== null;
}

public function user()
{
    if (! $this->user) {
        $this->check();
    }

    return $this->user;
}

protected function getTokenFromRequest()
{
    // Logic to extract JWT from request
}

protected function validateToken($token)
{
    // Logic to validate JWT
}

protected function getPayload($token)
{
    // Logic to decode and return JWT payload
}

Using Your Custom Guard

Once your guard is set up, you can use it like any other Laravel guard:

if (Auth::guard('api')->check()) {
    $user = Auth::guard('api')->user();
    // Do something with the authenticated user
}

You can also set it as the default guard for certain routes in your RouteServiceProvider:

protected function mapApiRoutes()
{
    Route::prefix('api')
         ->middleware('auth:api')
         ->namespace($this->namespace)
         ->group(base_path('routes/api.php'));
}

By creating custom authentication guards, you can tailor Laravel's authentication system to meet your specific needs. Whether you're implementing JWT, OAuth, or any other authentication method, custom guards provide the flexibility to integrate seamlessly with Laravel's existing authentication features.

If this guide was helpful to you, subscribe to my daily newsletter and give me a follow on X/Twitter. It helps a lot!

Subscribe to Harris Raftopoulos

Don’t miss out on the latest issues. Sign up now to get access to the library of members-only issues.
jamie@example.com
Subscribe