$client->id, 'token' => Str::random(64), 'expires_at' => $expiresInDays ? now()->addDays($expiresInDays) : null, ]); $this->logService->logOperation( 'client', $client->id, 'Generated new auth token' ); return $token; } public function generateAccessToken(AuthToken $authToken): array { $accessToken = Str::random(64); $expiresAt = now()->addSeconds(self::ACCESS_TOKEN_TTL); $tokenData = [ 'client_id' => $authToken->client_id, 'expires_at' => $expiresAt->toIso8601String(), ]; Redis::setex( self::ACCESS_TOKEN_PREFIX . $accessToken, self::ACCESS_TOKEN_TTL, json_encode($tokenData) ); $this->logService->logOperation( 'client', $authToken->client_id, 'Generated new access token' ); return [ 'access_token' => $accessToken, 'expires_in' => self::ACCESS_TOKEN_TTL, ]; } public function validateAuthToken(string $token): ?AuthToken { $authToken = AuthToken::where('token', $token)->first(); if (!$authToken || !$authToken->isValid()) { if ($authToken) { $this->logService->logOperation( 'client', $authToken->client_id, 'Invalid auth token attempt' ); } return null; } return $authToken; } public function validateAccessToken(string $token): ?array { $tokenData = Redis::get(self::ACCESS_TOKEN_PREFIX . $token); if (!$tokenData) { return null; } $data = json_decode($tokenData, true); $expiresAt = \DateTime::createFromFormat(\DateTime::ISO8601, $data['expires_at']); if ($expiresAt < now()) { $this->revokeAccessToken($token); $this->logService->logOperation( 'client', $data['client_id'], 'Access token expired' ); return null; } return $data; } public function revokeAccessToken(string $token): void { $tokenData = Redis::get(self::ACCESS_TOKEN_PREFIX . $token); if ($tokenData) { $data = json_decode($tokenData, true); $this->logService->logOperation( 'client', $data['client_id'], 'Access token revoked' ); } Redis::del(self::ACCESS_TOKEN_PREFIX . $token); } public function revokeAuthToken(AuthToken $authToken): void { $this->logService->logOperation( 'client', $authToken->client_id, 'Auth token revoked' ); $authToken->delete(); } }