SDK PHP (auris/sdk)
auris/sdk v0.1.0auris/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
curlabilitata - Estensione
opensslabilitata (per PKCE) - Estensione
sessionabilitata (per ilSessionTokenStorepredefinito)
Installazione
composer require auris/sdkClassi
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:
| Parametro | Tipo | Obbligatorio | Default | Descrizione |
|---|---|---|---|---|
domain | string | Sì | — | Dominio del tenant Auris, senza https:// |
clientId | string | Sì | — | Client ID dell’applicazione dalla Console |
redirectUri | string | Sì | — | Deve corrispondere esattamente a un Callback URL registrato |
clientSecret | ?string | No | null | Client secret per app server-side confidenziali |
scope | string | No | 'openid profile email' | Scope OAuth2 separati da spazio |
tenant | string | No | 'default' | Identificativo tenant |
tokenStore | ?TokenStore | No | null | Backend 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:
| Opzione | Tipo | Descrizione |
|---|---|---|
login_hint | string | Pre-compila il campo email |
screen_hint | 'signup' | Apre la schermata di registrazione |
prompt | 'login' | 'none' | Forza la ri-autenticazione o il controllo silenzioso |
locale | string | Locale dell’interfaccia (en, it, de, fr, es) |
connection | string | Forza 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:
| Codice | Descrizione |
|---|---|
invalid_state | Mismatch dello state CSRF — possibile attacco o sessione scaduta |
invalid_grant | Il codice di autorizzazione non è valido, è scaduto o già usato |
invalid_client | Client ID o redirect URI non corrisponde all’applicazione registrata |
network_error | La richiesta cURL all’API Auris è fallita |
token_expired | Il token di accesso è scaduto — chiama refreshToken() |
no_refresh_token | Nessun 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
- Plugin WordPress — Plugin SSO costruito sopra il PHP SDK
- Guida Login Ospitato — Flusso PKCE spiegato
- SDK JavaScript — Per integrazioni browser e Node.js