VOOZH about

URL: https://deepwiki.com/hypervel/auth/2.3.2-jwtguard

⇱ JwtGuard | hypervel/auth | DeepWiki


Loading...
Menu

JwtGuard

Purpose and Scope

The JwtGuard provides stateless authentication using JSON Web Tokens (JWT). It extracts and validates tokens from HTTP requests, decodes them to retrieve user identifiers, and manages token generation, refresh, and invalidation. This guard is designed for API authentication where server-side session storage is not desirable.

For session-based authentication, see SessionGuard. For custom authentication mechanisms, see RequestGuard. For the shared guard functionality used by all guards, see GuardHelpers Trait.

Sources: src/Guards/JwtGuard.php1-203


Architecture and Dependencies

The JwtGuard class implements the Guard contract and integrates multiple system components to provide JWT-based authentication.

Class Structure


Sources: src/Guards/JwtGuard.php19-31 src/Guards/GuardHelpers.php1-115

Constructor Dependencies

ParameterTypePurpose
$namestringGuard identifier used for context key namespacing
$providerUserProviderUser data retrieval abstraction
$jwtManagerManagerContractJWT encoding/decoding service from hypervel/jwt
$requestRequestInterfaceHTTP request for token extraction
$ttlintToken time-to-live in minutes (default: 120)

Sources: src/Guards/JwtGuard.php24-30


Token Parsing

The JwtGuard extracts JWT tokens from HTTP requests using a two-location fallback strategy.

Token Extraction Flow


Sources: src/Guards/JwtGuard.php51-68

Implementation Details

The parseToken() method implements the following extraction strategy:

  1. Context Check: Verifies that RequestContext::has() returns true to prevent errors when no request context exists
  2. Authorization Header: Extracts the token from the Authorization header if it starts with Bearer
  3. Request Parameter Fallback: Falls back to checking for a token parameter in the request body or query string
  4. Null Return: Returns null if no token is found in either location

This dual-location approach supports both standard Bearer token authentication (recommended) and parameter-based token passing (for compatibility).

Sources: src/Guards/JwtGuard.php51-68


User Authentication Flow

The JwtGuard resolves the authenticated user by decoding the JWT token and retrieving the user from the provider.

Authentication Sequence


Sources: src/Guards/JwtGuard.php98-122

Token Decoding and Validation

The user() method performs the following operations:

  1. Parse Token: Calls parseToken() to extract the token from the request
  2. Context Lookup: Checks if the user is already cached in the request context using the context key
  3. Token Decoding: Uses jwtManager->decode($token) to validate and decode the JWT
  4. Subject Extraction: Retrieves the sub claim from the decoded payload, which contains the user identifier
  5. User Retrieval: Calls provider->retrieveById($sub) to fetch the full user object
  6. Context Caching: Stores the result (user or null) in context for subsequent calls within the same request
  7. Exception Handling: Catches any Throwable during decoding (e.g., expired tokens, invalid signatures) and caches null

Sources: src/Guards/JwtGuard.php98-122

Context Key Strategy

The guard uses token-specific context keys to support multiple concurrent tokens in the same request:


Sources: src/Guards/JwtGuard.php89-96

The context key format is:

  • Without token: auth.guards.{$name}.result.default
  • With token: auth.guards.{$name}.result:{md5($token)}

This strategy allows the same guard to handle multiple tokens (useful during refresh operations) while preventing cache collisions.

Sources: src/Guards/JwtGuard.php89-96


Token Generation and Login

The login() method generates a new JWT token for an authenticated user and caches the user in context.

Token Generation Flow


Sources: src/Guards/JwtGuard.php70-87

JWT Payload Structure

The generated JWT token contains the following standard claims:

ClaimDescriptionValue
subSubject - user identifier$user->getAuthIdentifier()
iatIssued at timestampCurrent timestamp
expExpiration timestampCurrent timestamp + TTL minutes
Custom claimsAdditional claims via claims() methodMerged from context

Sources: src/Guards/JwtGuard.php70-87

Credential-Based Authentication

The attempt() method validates credentials and optionally logs in the user:


Sources: src/Guards/JwtGuard.php36-49

The attempt() method:

  1. Retrieves user by credentials using the user provider
  2. Validates credentials using provider->validateCredentials()
  3. If $login is true, calls login() to generate and cache a token
  4. Returns boolean indicating success or failure

Sources: src/Guards/JwtGuard.php36-49


Custom Claims

The JwtGuard supports adding custom claims to JWT tokens via the claims() method.

Claims Context Management


Sources: src/Guards/JwtGuard.php129-139

Usage Pattern

Custom claims are stored in request context and merged into the JWT payload during token generation. This allows chaining multiple claims() calls before login():


The context key used is auth.guards.{$name}.claims, where {$name} is the guard name.

Sources: src/Guards/JwtGuard.php129-139


Token Refresh

The refresh() method generates a new token from an existing valid token, extending the user's session.

Refresh Mechanism


Sources: src/Guards/JwtGuard.php152-161

Implementation Details

The refresh() method:

  1. Parse Token: Extracts the current token using parseToken()
  2. Clear Cache: Invalidates the cached user for the old token by setting its context value to null
  3. Delegate to JWT Manager: Calls jwtManager->refresh($token) which decodes the old token, generates a new token with fresh timestamps, and optionally invalidates the old token
  4. Return: Returns the new token string or null if no token exists

The cache clearing ensures that subsequent user() calls will use the new token instead of returning a cached user associated with the old token.

Sources: src/Guards/JwtGuard.php152-161


Logout and Token Invalidation

The logout() method invalidates the current token and clears the cached user.

Logout Flow


Sources: src/Guards/JwtGuard.php187-197

Invalidation Strategy

The logout() method performs two operations:

  1. Context Clearing: Sets the context cache to null, ensuring that user() calls within the same request will not return a cached user
  2. Token Invalidation: Delegates to jwtManager->invalidate($token) which typically adds the token to a blacklist or revocation list

The method always returns true, even if no token exists, indicating that logout was successful.

Sources: src/Guards/JwtGuard.php187-197


Context Caching Strategy

The JwtGuard uses Hyperf's request context to cache user resolution results, improving performance by avoiding repeated token decoding and database queries.

Cache Key Architecture


Sources: src/Guards/JwtGuard.php89-96 src/Guards/JwtGuard.php98-122 src/Guards/JwtGuard.php129-139

Cache Lifecycle

OperationCache ActionContext Key Used
user()Read then writeToken-specific: auth.guards.{name}.result:{md5(token)}
login()WriteDefault key if no current token, else token-specific
setUser()WriteDefault: auth.guards.{name}.result.default
refresh()Clear old token cacheOld token key
logout()Clear cacheCurrent token key

The caching strategy ensures:

  • Single Query: Database is queried only once per unique token per request
  • Token Isolation: Different tokens maintain separate cache entries
  • Refresh Support: Token refresh clears old cache to prevent stale data
  • Manual Override: setUser() allows bypassing token validation for testing or impersonation

Sources: src/Guards/JwtGuard.php98-122 src/Guards/JwtGuard.php70-87 src/Guards/JwtGuard.php152-161 src/Guards/JwtGuard.php187-197 src/Guards/JwtGuard.php199-202


Additional Methods

Payload Access

The getPayload() method exposes the decoded JWT payload without requiring authentication:


This method decodes the current token and returns the full payload array. On decode failure, it returns an empty array. This is useful for extracting custom claims without triggering full user resolution.

Sources: src/Guards/JwtGuard.php141-150

One-Time Authentication

The JwtGuard implements two methods for one-time authentication without persistent login:

MethodParametersReturnPurpose
once()array $credentialsboolValidates credentials and generates token
onceUsingId()mixed $idAuthenticatable|boolGenerates token for user ID

Both methods call login() to generate a token, but the intent is for single-use scenarios.

Sources: src/Guards/JwtGuard.php166-185

Manual User Setting

The setUser() method allows manually setting the authenticated user without token validation:


This bypasses token parsing and validation, storing the user directly in context using the default key. This is useful for testing, middleware, or scenarios where the user is already verified through other means.

Sources: src/Guards/JwtGuard.php199-202


Configuration

The JwtGuard is typically configured in the auth configuration file. Key configuration parameters:

ParameterTypeDefaultDescription
driverstring-Must be 'jwt' to use this guard
providerstring-User provider name (e.g., 'users')
ttlint120Token time-to-live in minutes

The guard is instantiated by the AuthManager based on configuration. The JWT manager dependency is resolved from the container and must be configured separately in the hypervel/jwt package.

Sources: src/Guards/JwtGuard.php24-31


Integration with Guard System

The JwtGuard inherits common guard functionality from the GuardHelpers trait:

MethodSourceDescription
authenticate()GuardHelpersThrows exception if not authenticated
check()GuardHelpersReturns boolean authentication status
guest()GuardHelpersReturns true if not authenticated
id()GuardHelpersReturns authenticated user ID
hasUser()GuardHelpersChecks if user is cached
loginUsingId()GuardHelpersLogs in by user ID
validate()GuardHelpersValidates credentials without login
getProvider()GuardHelpersReturns the user provider
setProvider()GuardHelpersSets the user provider

These methods delegate to user() and other guard-specific implementations.

Sources: src/Guards/GuardHelpers.php1-115 src/Guards/JwtGuard.php21