Skip to Content

SDK PHP (auris/sdk)

auris/sdk v0.1.0

auris/sdk è la libreria client PHP ufficiale per Auris IAM. Implementa il flusso OAuth2 Authorization Code con PKCE (S256) e fornisce un’API pulita per recuperare le informazioni utente e gestire i token.

La libreria non ha dipendenze esterne — usa solo i built-in PHP (curl, session, hash, openssl) e funziona con PHP 7.4 e versioni successive.


Requisiti

  • PHP 7.4 o superiore
  • Estensione curl abilitata
  • Estensione openssl abilitata (per PKCE)
  • Estensione session abilitata (per il SessionTokenStore predefinito)

Installazione

composer require auris/sdk

Classi

AurisConfig

Contiene tutta la configurazione per il client Auris. Passa un’istanza ad AurisClient.

use Auris\AurisConfig; $config = new AurisConfig( domain: 'auth.tuodominio.com', // Obbligatorio — dominio del tenant Auris clientId: 'app_xxxxx', // Obbligatorio — Client ID dell'applicazione redirectUri: 'https://app.com/callback.php', // Obbligatorio — deve essere registrato nella Console clientSecret: null, // Opzionale — solo per client confidenziali scope: 'openid profile email', // Opzionale — scope OAuth2 (default mostrato) tenant: 'my-tenant', // Opzionale — inviato come header x-tenant tokenStore: null, // Opzionale — istanza TokenStore personalizzata );

Parametri del costruttore:

ParametroTipoObbligatorioDefaultDescrizione
domainstringSì—Dominio del tenant Auris, senza https://
clientIdstringSì—Client ID dell’applicazione dalla Console
redirectUristringSì—Deve corrispondere esattamente a un Callback URL registrato
clientSecret?stringNonullClient secret per app server-side confidenziali
scopestringNo'openid profile email'Scope OAuth2 separati da spazio
tenantstringNo'default'Identificativo tenant
tokenStore?TokenStoreNonullBackend di archiviazione personalizzato. Default SessionTokenStore.

AurisClient

La classe client principale. Instanziala con un oggetto AurisConfig.

use Auris\AurisClient; use Auris\AurisConfig; $config = new AurisConfig( domain: 'auth.tuodominio.com', clientId: 'your-client-id', redirectUri: 'https://tua-app.com/callback.php' ); $auris = new AurisClient($config);

getLoginUrl(options?): string

Genera l’URL di login ospitato da Auris inclusi i parametri PKCE e un token CSRF. Il code verifier PKCE e lo state vengono memorizzati automaticamente nella sessione.

// Reindirizza alla pagina di login ospitata $loginUrl = $auris->getLoginUrl(); header('Location: ' . $loginUrl); exit; // Con opzioni aggiuntive $loginUrl = $auris->getLoginUrl([ 'login_hint' => '[email protected]', 'screen_hint' => 'signup', 'locale' => 'it', 'prompt' => 'login', ]);

Opzioni disponibili:

OpzioneTipoDescrizione
login_hintstringPre-compila il campo email
screen_hint'signup'Apre la schermata di registrazione
prompt'login' | 'none'Forza la ri-autenticazione o il controllo silenzioso
localestringLocale dell’interfaccia (en, it, de, fr, es)
connectionstringForza una connessione SSO specifica

handleCallback(code, state): TokenResult

Scambia il codice di autorizzazione ricevuto sull’URL di callback per i token. Valida il parametro state rispetto al valore memorizzato per prevenire attacchi CSRF.

Lancia AurisException se lo state non è valido, lo scambio del codice fallisce, o la richiesta di rete genera un errore.

// callback.php session_start(); try { $result = $auris->handleCallback( code: $_GET['code'] ?? '', state: $_GET['state'] ?? '' ); // I token sono ora memorizzati nella sessione echo 'Autenticato! Il token di accesso scade in ' . $result->expiresIn . ' secondi.'; } catch (Auris\AurisException $e) { http_response_code(400); echo 'Autenticazione fallita: ' . htmlspecialchars($e->getMessage()); }

isAuthenticated(): bool

Restituisce true se l’utente ha un token di accesso valido (non scaduto) memorizzato nella sessione corrente.

if (!$auris->isAuthenticated()) { header('Location: /login.php'); exit; }

getUser(): ?AurisUser

Restituisce l’utente attualmente autenticato decodificando il token ID memorizzato. Restituisce null se non c’è una sessione attiva.

$user = $auris->getUser(); if ($user !== null) { echo 'Ciao, ' . htmlspecialchars($user->firstName); echo ' (ID: ' . $user->id . ')'; echo ' Ruoli: ' . implode(', ', $user->roles); }

getAccessToken(): ?string

Restituisce la stringa del token di accesso memorizzato, o null se non autenticato. Usa questo token nelle intestazioni Authorization: Bearer quando chiami la tua API.

$token = $auris->getAccessToken(); if ($token !== null) { $ch = curl_init('https://api.tuaapp.com/data'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: Bearer ' . $token, 'Accept: application/json', ]); $response = curl_exec($ch); curl_close($ch); }

refreshToken(): TokenResult

Scambia il refresh token memorizzato per una nuova coppia di token di accesso e refresh. Aggiorna automaticamente i token memorizzati.

Lancia AurisException se nessun refresh token è disponibile o il refresh fallisce.

try { $result = $auris->refreshToken(); echo 'Nuovo token di accesso scade in ' . $result->expiresIn . ' secondi.'; } catch (Auris\AurisException $e) { // Refresh fallito — reindirizza al login header('Location: /login.php'); exit; }

logout(returnTo?): void

Cancella i token memorizzati dalla sessione e opzionalmente reindirizza il browser.

// Cancella i token e reindirizza alla home page $auris->logout(returnTo: 'https://tua-app.com/');

Pkce

Classe helper statica per generare i parametri PKCE. Di solito non hai bisogno di chiamarli direttamente — AurisClient::getLoginUrl() gestisce PKCE automaticamente. Questi sono esposti per integrazioni personalizzate.

use Auris\Pkce; // Genera un code verifier da 128 byte (base64 URL-safe, 43–128 caratteri) $verifier = Pkce::generateVerifier(); // Deriva il code challenge S256 dal verifier $challenge = Pkce::generateChallenge($verifier); // Genera una stringa state casuale crittograficamente sicura (protezione CSRF) $state = Pkce::generateState();

TokenResult

Restituito da handleCallback() e refreshToken(). Contiene i dati token grezzi dall’endpoint token di Auris.

class TokenResult { public string $accessToken; public ?string $refreshToken; public int $expiresIn; // Secondi alla scadenza del token di accesso public string $tokenType; // Sempre 'Bearer' public ?string $idToken; // JWT contenente i claim utente public function getUser(): AurisUser; // Decodifica le informazioni utente dall'ID token }

AurisUser

Rappresenta l’utente autenticato, decodificato dall’ID token.

class AurisUser { public string $id; // ID utente Auris public string $sub; // Claim subject JWT (uguale a $id) public string $email; public bool $emailVerified; public string $name; // Nome visualizzato completo public string $firstName; public string $lastName; public string $username; public ?string $picture; // URL foto profilo public array $roles; // string[] — nomi dei ruoli assegnati public array $metadata; // Metadati chiave-valore personalizzati public string $tenant; public string $createdAt; }

TokenStore e SessionTokenStore

TokenStore è l’interfaccia per persistere i token tra le richieste. L’implementazione predefinita SessionTokenStore memorizza i token nella $_SESSION nativa di PHP.

SessionTokenStore viene usato automaticamente quando non viene fornito uno store personalizzato. Richiede che session_start() sia stato chiamato prima di instanziare AurisClient.

Per usare un backend personalizzato, implementa l’interfaccia TokenStore:

use Auris\TokenStore; class DatabaseTokenStore implements TokenStore { public function __construct( private \PDO $pdo, private string $userId ) {} public function get(string $key): ?string { $stmt = $this->pdo->prepare( 'SELECT value FROM auris_tokens WHERE user_id = :uid AND key = :key' ); $stmt->execute([':uid' => $this->userId, ':key' => $key]); $row = $stmt->fetch(\PDO::FETCH_ASSOC); return $row ? $row['value'] : null; } public function set(string $key, string $value): void { $stmt = $this->pdo->prepare( 'INSERT INTO auris_tokens (user_id, key, value) VALUES (:uid, :key, :val) ON DUPLICATE KEY UPDATE value = :val' ); $stmt->execute([':uid' => $this->userId, ':key' => $key, ':val' => $value]); } public function remove(string $key): void { $stmt = $this->pdo->prepare( 'DELETE FROM auris_tokens WHERE user_id = :uid AND key = :key' ); $stmt->execute([':uid' => $this->userId, ':key' => $key]); } } // Passa lo store personalizzato tramite AurisConfig $config = new AurisConfig( domain: 'auth.tuodominio.com', clientId: 'your-client-id', redirectUri: 'https://tua-app.com/callback.php', tokenStore: new DatabaseTokenStore($pdo, $currentUserId) );

AurisException

Lanciata da AurisClient in caso di errore. Contiene un $code leggibile dalla macchina e un $message leggibile dall’uomo.

class AurisException extends \RuntimeException { public string $code; // Codice di errore leggibile dalla macchina public int $httpStatus; // Codice di stato HTTP (0 per errori di rete) }

Codici di errore comuni:

CodiceDescrizione
invalid_stateMismatch dello state CSRF — possibile attacco o sessione scaduta
invalid_grantIl codice di autorizzazione non è valido, è scaduto o già usato
invalid_clientClient ID o redirect URI non corrisponde all’applicazione registrata
network_errorLa richiesta cURL all’API Auris è fallita
token_expiredIl token di accesso è scaduto — chiama refreshToken()
no_refresh_tokenNessun refresh token in sessione — l’utente deve effettuare nuovamente il login

Esempio PHP Vanilla

Un flusso di login completo in quattro file:

<?php // login.php — reindirizza al login ospitato da Auris require 'vendor/autoload.php'; use Auris\AurisClient; use Auris\AurisConfig; session_start(); $config = new AurisConfig( domain: 'auth.tuodominio.com', clientId: 'your-client-id', redirectUri: 'http://localhost:8000/callback.php' ); $auris = new AurisClient($config); header('Location: ' . $auris->getLoginUrl()); exit;
<?php // callback.php — gestisce il redirect da Auris require 'vendor/autoload.php'; use Auris\AurisClient; use Auris\AurisConfig; use Auris\AurisException; session_start(); $config = new AurisConfig( domain: 'auth.tuodominio.com', clientId: 'your-client-id', redirectUri: 'http://localhost:8000/callback.php' ); $auris = new AurisClient($config); try { $auris->handleCallback( code: $_GET['code'] ?? '', state: $_GET['state'] ?? '' ); header('Location: /dashboard.php'); exit; } catch (AurisException $e) { http_response_code(400); echo '<p>Accesso fallito: ' . htmlspecialchars($e->getMessage()) . '</p>'; echo '<a href="/login.php">Riprova</a>'; }
<?php // dashboard.php — pagina protetta require 'vendor/autoload.php'; use Auris\AurisClient; use Auris\AurisConfig; session_start(); $config = new AurisConfig( domain: 'auth.tuodominio.com', clientId: 'your-client-id', redirectUri: 'http://localhost:8000/callback.php' ); $auris = new AurisClient($config); if (!$auris->isAuthenticated()) { header('Location: /login.php'); exit; } $user = $auris->getUser(); ?> <!DOCTYPE html> <html lang="it"> <head><title>Dashboard</title></head> <body> <h1>Benvenuto, <?= htmlspecialchars($user->firstName) ?></h1> <p>Email: <?= htmlspecialchars($user->email) ?></p> <p>Ruoli: <?= htmlspecialchars(implode(', ', $user->roles)) ?></p> <a href="/logout.php">Esci</a> </body> </html>
<?php // logout.php — cancella la sessione e reindirizza require 'vendor/autoload.php'; use Auris\AurisClient; use Auris\AurisConfig; session_start(); $config = new AurisConfig( domain: 'auth.tuodominio.com', clientId: 'your-client-id', redirectUri: 'http://localhost:8000/callback.php' ); $auris = new AurisClient($config); $auris->logout(returnTo: 'http://localhost:8000/');

Integrazione Laravel

Service Provider

Registra AurisClient nel container dei servizi Laravel come singleton:

// app/Providers/AurisServiceProvider.php namespace App\Providers; use Auris\AurisClient; use Auris\AurisConfig; use Illuminate\Support\ServiceProvider; class AurisServiceProvider extends ServiceProvider { public function register(): void { $this->app->singleton(AurisClient::class, function () { $config = new AurisConfig( domain: config('auris.domain'), clientId: config('auris.client_id'), redirectUri: config('auris.redirect_uri'), clientSecret: config('auris.client_secret'), tenant: config('auris.tenant', 'default'), ); return new AurisClient($config); }); } }

File di Configurazione

// config/auris.php return [ 'domain' => env('AURIS_DOMAIN'), 'client_id' => env('AURIS_CLIENT_ID'), 'client_secret' => env('AURIS_CLIENT_SECRET'), 'redirect_uri' => env('AURIS_REDIRECT_URI'), 'tenant' => env('AURIS_TENANT', 'default'), ];

Controller

// app/Http/Controllers/AuthController.php namespace App\Http\Controllers; use Auris\AurisClient; use Auris\AurisException; use Illuminate\Http\Request; class AuthController extends Controller { public function __construct(private AurisClient $auris) {} public function login() { return redirect($this->auris->getLoginUrl()); } public function callback(Request $request) { try { $this->auris->handleCallback( $request->query('code', ''), $request->query('state', '') ); return redirect('/dashboard'); } catch (AurisException $e) { return redirect('/login')->withErrors(['auth' => $e->getMessage()]); } } public function logout() { $this->auris->logout(returnTo: config('app.url')); return redirect('/'); } }

Middleware

// app/Http/Middleware/RequireAurisAuth.php namespace App\Http\Middleware; use Auris\AurisClient; use Closure; use Illuminate\Http\Request; class RequireAurisAuth { public function __construct(private AurisClient $auris) {} public function handle(Request $request, Closure $next) { if (!$this->auris->isAuthenticated()) { return redirect('/login'); } return $next($request); } }
// routes/web.php use App\Http\Controllers\AuthController; use App\Http\Middleware\RequireAurisAuth; Route::get('/auth/login', [AuthController::class, 'login']); Route::get('/auth/callback', [AuthController::class, 'callback']); Route::get('/auth/logout', [AuthController::class, 'logout']); Route::middleware(RequireAurisAuth::class)->group(function () { Route::get('/dashboard', fn() => view('dashboard')); Route::get('/impostazioni', fn() => view('impostazioni')); });

Correlati