VOOZH about

URL: https://deepwiki.com/hypervel/auth/2.4.3-custom-user-providers

⇱ Custom User Providers | hypervel/auth | DeepWiki


Loading...
Menu

Custom User Providers

Purpose and Scope

This document explains how to create and register custom user providers for specialized user storage systems beyond the built-in Eloquent and Database providers. Custom providers enable authentication against alternative storage mechanisms such as LDAP directories, external APIs, Redis, MongoDB, or any custom user repository.

For information about the standard user provider implementations, see EloquentUserProvider and DatabaseUserProvider. For the UserProvider contract specification, see UserProvider Contract. For general user provider concepts, see User Providers.


When to Use Custom User Providers

Custom user providers are necessary when your application needs to authenticate users from sources that cannot be accessed through Eloquent models or direct database queries. Common scenarios include:

Use CaseDescription
LDAP/Active DirectoryAuthenticate against corporate directory services
External APIsValidate credentials via third-party authentication APIs
NoSQL DatabasesAccess user data from MongoDB, Redis, or similar systems
MicroservicesRetrieve users from remote user management services
Legacy SystemsIntegrate with existing custom authentication databases
Multi-tenancyImplement tenant-specific user retrieval logic

Sources: Context from architecture diagrams and src/CreatesUserProviders.php32-38


The UserProvider Contract

All user providers must implement the Hypervel\Auth\Contracts\UserProvider interface, which defines the following methods:

MethodPurposeReturn Type
retrieveById($identifier)Retrieve a user by their unique identifier?Authenticatable
retrieveByCredentials(array $credentials)Retrieve a user by the given credentials (typically including username/email)?Authenticatable
validateCredentials(Authenticatable $user, array $credentials)Validate a user against the given credentials (typically password verification)bool

The methods must return objects implementing the Authenticatable contract. For non-Eloquent providers, you can use the GenericUser class src/GenericUser.php9-90 or create your own Authenticatable implementation.

Sources: src/CreatesUserProviders.php8 src/GenericUser.php9-90


Registration Mechanism

Custom user providers are registered using the provider() method on the AuthManager instance. This method accepts a provider name and a closure that creates the provider instance.

Registration Method Signature

AuthManager::provider(string $name, Closure $callback): static

The method is defined at src/AuthManager.php144-149 and stores the callback in the $customProviderCreators array managed by the CreatesUserProviders trait src/CreatesUserProviders.php19

Provider Creator Callback Signature

The callback receives two parameters:

ParameterTypeDescription
$appContainerInterfaceThe application's dependency injection container
$configarrayProvider configuration from auth.providers.{name}

The callback must return an instance implementing UserProvider.

Sources: src/AuthManager.php144-149 src/CreatesUserProviders.php32-38


Provider Creation Flow

The following diagram illustrates how custom providers are registered and subsequently created when needed by guards:


Sources: src/AuthManager.php144-149 src/CreatesUserProviders.php26-47 src/AuthManager.php104-111


Custom Provider Registration

Custom providers are typically registered in a service provider's boot() method or application bootstrap phase. The registration must occur before any guards attempt to use the provider.

Registration Example Structure

The registration process involves three steps:

  1. Define Provider Configuration in config/auth.php:

  1. Register Custom Provider Creator:

  1. Configure Guard to Use Provider:

Sources: src/AuthManager.php144-149 src/CreatesUserProviders.php26-47 src/AuthManager.php222-225


Custom Provider Implementation

The following diagram shows the relationship between a custom provider implementation and the authentication system components:


Sources: src/CreatesUserProviders.php8 src/GenericUser.php9-90 src/CreatesUserProviders.php32-38


Implementation Requirements

Method Implementation Guidelines

Each method in the UserProvider interface has specific responsibilities:

retrieveById($identifier)

  • Receives a unique user identifier (typically an integer or string ID)
  • Queries the custom storage system to find the user
  • Returns an Authenticatable instance or null if not found
  • Used by guards when resuming authentication from stored identifiers (sessions, JWT tokens)

retrieveByCredentials(array $credentials)

  • Receives an array of credentials (typically ['email' => '...', 'password' => '...'])
  • Searches for a user matching the identifying credentials (email, username, etc.)
  • Must not validate the password - only retrieve the user
  • Returns an Authenticatable instance or null if not found
  • The password key should be ignored during user lookup

validateCredentials(Authenticatable $user, array $credentials)

  • Receives a user instance and credentials array
  • Validates that the credentials match the user (typically password verification)
  • Returns boolean indicating whether credentials are valid
  • This method is separate from retrieval to support multiple credential types

Sources: src/CreatesUserProviders.php8 src/Providers/DatabaseUserProvider.php42-88 (reference implementation)


Integration with AuthManager

The AuthManager class uses the CreatesUserProviders trait to manage both built-in and custom providers. When a guard is created, it requests a provider by name, triggering the provider creation flow.

Provider Resolution Logic


Sources: src/CreatesUserProviders.php26-47 src/AuthManager.php104-111 src/AuthManager.php116-125


Code Reference Map

The following table maps the key components involved in custom provider registration to their locations in the codebase:

ComponentFile LocationDescription
AuthManager::provider()src/AuthManager.php144-149Public method to register custom providers
$customProviderCreatorssrc/CreatesUserProviders.php19Array storing custom provider callbacks
createUserProvider()src/CreatesUserProviders.php26-47Resolves and creates provider instances
Custom provider checksrc/CreatesUserProviders.php32-38Checks for and invokes custom creators
GenericUsersrc/GenericUser.php9-90Simple Authenticatable implementation for custom providers
Provider configurationsrc/CreatesUserProviders.php54-61Retrieves provider config from auth.providers

Sources: src/AuthManager.php1-255 src/CreatesUserProviders.php1-96 src/GenericUser.php1-90


Usage in Guard Creation

When guards are instantiated, they receive a user provider created through the AuthManager. The following shows how this integration occurs:

Session Guard Provider Injection

At src/AuthManager.php104-111 the createSessionDriver() method demonstrates how providers are passed to guards:


JWT Guard Provider Injection

Similarly, at src/AuthManager.php116-125 the createJwtDriver() method follows the same pattern:


This design ensures that custom providers work seamlessly with all guard types without requiring guard modifications.

Sources: src/AuthManager.php104-125


Example Use Cases

LDAP Authentication Provider

A custom LDAP provider would:

  • Connect to an LDAP server in the constructor
  • Search the directory in retrieveByCredentials() using the email/username
  • Bind with user credentials in validateCredentials() to verify passwords
  • Return GenericUser instances populated with LDAP attributes

API-Based Authentication

A custom API provider would:

  • Make HTTP requests to a user management API
  • Cache user data to minimize API calls
  • Transform API responses into Authenticatable objects
  • Handle API authentication tokens in the constructor

Redis User Cache

A custom Redis provider could:

  • Query Redis for fast user lookups
  • Fall back to a database provider if cache miss occurs
  • Implement cache-warming strategies
  • Maintain cache consistency with the source of truth

Sources: Context from architecture diagrams and src/CreatesUserProviders.php26-47


Best Practices

PracticeRationale
Separate credential lookup from validationThe retrieveByCredentials() method should never validate passwords - that's the role of validateCredentials()
Handle null returns gracefullyReturn null when users aren't found rather than throwing exceptions
Use dependency injectionAccept dependencies like connections or API clients in the constructor, resolved from the container
Implement caching when appropriateExternal systems may be slow - consider caching user objects within the request lifecycle
Return Authenticatable instancesUse GenericUser for simple cases or create custom classes implementing Authenticatable
Validate configurationCheck required configuration keys in the provider creator callback

Sources: src/Providers/DatabaseUserProvider.php42-88 (reference implementation pattern), src/GenericUser.php9-90