|
- <?php
-
- declare(strict_types=1);
-
- namespace App\Services;
-
- use Core\Response;
- use Stevenmaguire\OAuth2\Client\Provider\Keycloak;
-
- class AuthService
- {
- private static function config(): array
- {
- static $config = null;
-
- if ($config === null) {
- $config = require __DIR__ . '/../../config/auth.php';
- }
-
- return $config['keycloak'];
- }
-
- public static function provider(): Keycloak
- {
- $cfg = self::config();
-
- return new Keycloak([
- 'authServerUrl' => rtrim($cfg['base_url'], '/'),
- 'realm' => $cfg['realm'],
- 'clientId' => $cfg['client_id'],
- 'clientSecret' => $cfg['client_secret'],
- 'redirectUri' => $cfg['redirect_uri'],
- ]);
- }
-
- /**
- * Decode user claims from the access token JWT payload.
- * Avoids calling the userinfo endpoint, which Keycloak may return as a
- * signed JWT (application/jwt) rather than JSON — causing decryption errors.
- *
- * @return array<string, mixed>
- */
- public static function claimsFromToken(string $jwt): array
- {
- $parts = explode('.', $jwt);
- if (count($parts) < 2) {
- return [];
- }
-
- $payload = base64_decode(strtr($parts[1], '-_', '+/'), true);
- if ($payload === false) {
- return [];
- }
-
- $data = json_decode($payload, true);
-
- return is_array($data) ? $data : [];
- }
-
- public static function requireLogin(): ?Response
- {
- if (!self::isLoggedIn()) {
- $_SESSION['auth_return_to'] = $_SERVER['REQUEST_URI'] ?? '/';
- return Response::redirect('/auth/login');
- }
-
- return null;
- }
-
- public static function isLoggedIn(): bool
- {
- return !empty($_SESSION['auth_user']);
- }
-
- public static function getCurrentUser(): array
- {
- return $_SESSION['auth_user'] ?? [];
- }
-
- public static function getCurrentUsername(): string
- {
- $user = self::getCurrentUser();
-
- return $user['preferred_username'] ?? $user['email'] ?? '';
- }
-
- public static function storeUser(array $userInfo): void
- {
- $_SESSION['auth_user'] = $userInfo;
- }
-
- public static function clearSession(): void
- {
- $_SESSION = [];
-
- if (ini_get('session.use_cookies')) {
- $params = session_get_cookie_params();
- setcookie(
- session_name(),
- '',
- time() - 42000,
- $params['path'],
- $params['domain'],
- $params['secure'],
- $params['httponly']
- );
- }
-
- session_destroy();
- }
-
- public static function logoutUrl(): string
- {
- $cfg = self::config();
- $base = rtrim($cfg['base_url'], '/');
- $realm = $cfg['realm'];
- $postLogout = urlencode($cfg['post_logout_redirect_uri']);
-
- return "{$base}/realms/{$realm}/protocol/openid-connect/logout?redirect_uri={$postLogout}";
- }
- }
|