VOOZH about

URL: https://deepwiki.com/mathsgod/light/5.4-auth-service

⇱ Auth Service | mathsgod/light | DeepWiki


Loading...
Last indexed: 31 January 2026 (cf9511)
Menu

Auth Service

The Auth Service (Light\Auth\Service) manages authentication state for individual HTTP requests. It extracts and validates JWT tokens from Authorization headers or cookies, checks for revoked tokens via cache, provides current user context to GraphQL resolvers, supports administrator impersonation (view-as mode), and integrates with GraphQLite's authentication and authorization systems.

For information about the authentication flow (login, logout, password verification), see page 5.1. For details on JWT token generation and structure, see page 5.2.2. For RBAC permission checking, see page 5.5. For the User model, see page 5.3.

Purpose and Scope

The Light\Auth\Service class acts as a per-request authentication context that:

  1. Extracts JWT tokens from Authorization headers (Bearer scheme) or access_token cookies
  2. Decodes and validates token claims using Firebase\JWT\JWT::decode()
  3. Checks if tokens have been revoked via cache lookup with key pattern revoked_token_{jti}
  4. Retrieves the current authenticated Light\Model\User instance by ID from token payload
  5. Supports view-as mode for administrator impersonation with separate original user tracking
  6. Handles token expiration by throwing Light\TokenExpiredException on expired tokens
  7. Implements GraphQLite's AuthenticationServiceInterface and AuthorizationServiceInterface
  8. Updates last access time in UserLog table for active sessions (except in view-as mode)

The service is instantiated once per request during the Light\App::process() middleware phase and injected into GraphQL resolvers via dependency injection.

Class Structure


Sources: src/Auth/Service.php1-140

Service Initialization

The Light\Auth\Service is created during request processing in the Light\App::process() middleware method. The constructor performs all authentication and validation logic synchronously.

Constructor Flow in Auth\Service


Sources: src/Auth/Service.php28-80

Registration in App Class

The service is registered in three places within Light\App::process():

StepMethod CallPurpose
1new Auth\Service($request)Create instance with request context
2$this->schemaFactory->setAuthenticationService($auth_service)Enable @Logged annotations
3$this->schemaFactory->setAuthorizationService($auth_service)Enable @Right annotations
4$container->add(Auth\Service::class, $auth_service)Make available for #[Autowire] injection

Sources: src/Auth/Service.php28-80

JWT Token Extraction

The Auth Service extracts the JWT token from two possible sources:

Token Extraction Strategy


Sources: src/Auth/Service.php28-48

Token Storage and Retrieval

AspectImplementation
Primary LocationHttpOnly cookie named access_token
Alternative LocationAuthorization header with Bearer scheme
Set DuringApp::userLogin() after successful authentication
Cookie LifetimeConfigured via access_token_expire in Config table
Security Flagshttponly: true, secure (configurable), samesite (configurable)
Extraction OrderAuthorization header checked first, then cookie fallback

The service constructor first checks for a Bearer token in the Authorization header using the pattern /Bearer\s(\S+)/. If not found, it falls back to reading the access_token cookie. This dual-source approach supports both traditional web browser sessions (cookies) and modern API clients (Authorization headers).

Sources: src/Auth/Service.php37-43

Token Validation

The __construct() method performs JWT validation using Firebase\JWT\JWT::decode() with the HS256 algorithm and the JWT_SECRET environment variable:

JWT Validation in Constructor


JWT Payload Structure

The access token decoded at src/Auth/Service.php51 contains these claims:

ClaimTypeDescriptionSource
issstringIssuer: "light server"Token generation
jtistringJWT ID: UUID v4 for revocationToken generation
iatintIssued at timestampToken generation
expintExpiration timestampToken generation
idintUser ID for User::Get() lookupToken generation
typestringMust be "access_token"Checked at line 52
view_asintOptional: target user ID for impersonationAdmin feature

Sources: src/Auth/Service.php50-74

Token Revocation Check

The constructor checks if a token has been revoked by performing a cache lookup immediately after JWT decoding:

Revocation Check Flow


Cache Key Pattern: revoked_token_{jti} where {jti} is the JWT ID claim (UUID v4)

Revocation Implementation Details:

  • Check performed at src/Auth/Service.php58 immediately after decoding
  • Early return at src/Auth/Service.php59 if cache hit occurs
  • User remains anonymous (is_logged = false) even with valid JWT signature
  • Cache keys set during logout operations with TTL matching token expiration
  • No database query required for revocation check (cache-only)

Integration with Logout

Logout operations store the revoked JTI by calling $cache->set('revoked_token_{jti}', true, $ttl) where $ttl is the remaining token lifetime. This ensures:

  1. Immediate invalidation (no race conditions)
  2. Automatic cleanup when token would have expired anyway
  3. Minimal cache storage (only active token JTIs)

Sources: src/Auth/Service.php56-60

GraphQLite Integration

The Auth Service implements GraphQLite's authentication and authorization service interfaces:

GraphQLite Service Integration


Sources: src/App.php495-496

The integration enables:

  1. @Logged Annotation: Resolvers marked with #[Logged] automatically require authentication src/Controller/AuthController.php75 src/Controller/AuthController.php426
  2. @InjectUser Parameter: Resolvers can inject the current User model src/Controller/AuthController.php420 src/Controller/AuthController.php427
  3. @Right Annotation: Permission checks are delegated to the Auth Service src/Controller/AuthController.php76

Current User Access

The Auth Service provides the current authenticated User model to GraphQL resolvers:

User Injection Patterns


Sources: src/Controller/AuthController.php420-423 src/Controller/AuthController.php427-441 src/Controller/AuthController.php303-328

View As Mode (Administrator Impersonation)

The service supports administrator impersonation when the JWT payload contains a view_as claim. This allows administrators to experience the application as another user while preserving audit trail.

View As Mode Implementation


Property Assignments in View As Mode:

PropertyNormal ModeView As ModePurpose
$this->view_asfalsetrue (line 65)Flag for isViewAsMode()
$this->userAuthenticated userTarget impersonated user (line 66)Returned by getUser()
$this->org_usernullOriginal administrator (line 67)Returned by getOrginalUser()
Last access trackingUpdated via saveLastAccessTime()NOT updatedView-as sessions not tracked

Method Behavior with View As:


Use Cases:

  • Administrator testing user permissions without switching accounts
  • Support staff troubleshooting user-specific issues
  • Audit trail preservation (actions logged under original admin identity)
  • Permission debugging in production environments

Sources: src/Auth/Service.php64-120

Token Expiration Handling

The service distinguishes between expired tokens and invalid/missing tokens by catching Firebase\JWT\ExpiredException and storing the expiration state in the $token_status property:

Expiration Detection in Constructor


Lazy Exception Throwing in Getters

The constructor catches expiration but does not throw. Instead, isLogged() and getUser() check $token_status and throw on access:


Exception Timing:

ScenarioConstructor BehaviorGetter Behavior
Missing tokenSilent (anonymous)Returns false/null
Invalid signatureSilent (anonymous)Returns false/null
Expired tokenCatches ExpiredException, sets flagThrows TokenExpiredException
Valid tokenNormal processingReturns true/User

Purpose: Deferred exception throwing allows GraphQL error handlers to distinguish expired tokens (which should trigger refresh flows) from missing authentication (which should show login prompts).

Sources: src/Auth/Service.php75-113

Public Methods

The Light\Auth\Service class provides seven public methods:

MethodReturn TypeLinesPurpose
getToken()?string82-85Returns raw JWT token string extracted from request
getJti()?string87-90Returns JWT ID claim for revocation tracking
isViewAsMode()bool92-95Returns true if current session uses administrator impersonation
isLogged()bool98-105Returns true if authenticated; throws TokenExpiredException if expired
getUser()?object107-113Returns current User model (or impersonated user); throws if expired
getOrginalUser()?object115-120Returns original user (admin in view-as mode) or current user
isAllowed(string $right)bool122-139Checks permission via RBAC; auto-grants to "Administrators" role

Method Implementation Details:

getToken() - Line 82-85


Returns the raw JWT string stored during construction. Used for token refresh operations.

getJti() - Lines 87-90


Returns the JWT ID extracted from payload->jti. Used for revocation and session tracking.

isLogged() - Lines 98-105


Throws Light\TokenExpiredException if token expired. Otherwise returns boolean authentication state.

getOrginalUser() - Lines 115-120


Returns org_user if set (view-as mode), else returns user. Used for audit trails.

isAllowed(string $right) - Lines 122-139


Automatically returns true for users with "Administrators" role (lines 132-134). Otherwise delegates to RBAC system.

Sources: src/Auth/Service.php82-139

Request Lifecycle Integration

The Light\Auth\Service is instantiated early in the request pipeline and used throughout GraphQL query execution:

Auth Service in Complete Request Flow


Integration Points:

PhaseComponentAuth Service Usage
Request parsingApp::process()Creates service instance
Schema setupSchemaFactoryRegistered as authentication/authorization provider
Field resolutionGraphQL executorChecks #[Logged] annotations via isLogged()
Parameter injectionGraphQL executorInjects User via #[InjectUser] using getUser()
Permission checksGraphQL executorValidates #[Right] annotations via isAllowed()
Business logicControllers/ResolversAccesses via #[Autowire] Service $service

Sources: src/Auth/Service.php28-80

Drive Access Control

The Auth Service also controls access to file storage:

When a GET request is made to /drive/{index}/{path}, the system checks authentication:


Sources: src/App.php502-520

This ensures only authenticated users can access files via direct URLs.

Anonymous User Context

When no valid token is present or the token is revoked/expired, the service operates in anonymous mode:

Anonymous User Behavior:

Method/FeatureAnonymous Mode Behavior
isLogged()Returns false
getUser()Returns null
getJti()Returns null
isViewAsMode()Returns false
isAllowed($right)Returns false
#[InjectUser] ?User $userParameter receives null
#[Logged] annotationGraphQL request rejected with authentication error
#[Right] annotationGraphQL request rejected with authorization error
Public queries/mutationsRemain accessible (no annotations)

Anonymous State Triggers:

  • No Authorization header and no access_token cookie
  • JWT signature validation fails
  • Token type is not "access_token"
  • Cache contains revoked_token_{jti} key
  • User::Get($id) returns null (user deleted)

Example Anonymous Access:


Sources: src/Auth/Service.php98-139

Security Considerations

The Auth Service implements several security measures:

  1. HttpOnly Cookies: Prevents XSS attacks from stealing tokens src/App.php626
  2. Token Revocation: Immediate invalidation via cache src/Controller/AuthController.php308
  3. Short Lifetimes: Configurable token expiration (default 8 hours) src/App.php586
  4. Secure Flag: HTTPS-only transmission (configurable) src/App.php625
  5. SameSite: CSRF protection (configurable) src/App.php627

Sources: src/App.php621-628 src/Controller/AuthController.php303-328