AuthService
Cosa fa
AuthService e il servizio applicativo che orchestra tutte le operazioni di autenticazione contro un backend REST. Implementa contemporaneamente:
IAuthService— operazioni di dominio (login, logout, register, ecc.)IAuthHandler— intercettore di errori 401 per il client HTTP, con refresh token automatico
Delega la persistenza dei token a un IAuthStrategy iniettato, restando agnostico dal meccanismo di storage.
Costruttore
class AuthService implements IAuthService, IAuthHandler {
constructor(
httpClient: IHttpClient,
authStrategy: IAuthStrategy,
logger?: ILogger
)
}
| Parametro | Tipo | Default | Descrizione |
|---|---|---|---|
httpClient | IHttpClient | — | Client HTTP per le request /auth/* |
authStrategy | IAuthStrategy | — | Strategia per la persistenza di token e refresh token |
logger | ILogger | new ConsoleLogger() | Logger per errori/warning |
AuthServiceFactory.create(...) per uniformare lo stile factory del package.Endpoint utilizzati
Tutti gli endpoint sono convention-based e devono essere esposti dal backend con il prefisso assoluto/relativo configurato sul client HTTP:
| Metodo | URL | Body |
|---|---|---|
login | POST /auth/login | UserCredentials |
logout | POST /auth/logout | { refreshToken } |
register | POST /auth/register | RegisterUser |
activateAccount | GET /auth/activate-account?token=... | — |
forgotPassword | POST /auth/forgot-password | ForgotPassword |
resetPassword | POST /auth/reset-password | ResetPassword |
refreshToken | POST /auth/refresh-token | { refreshToken } |
Metodi principali
login(credentials): Promise<AuthResponse | null>
Effettua il login. In caso di successo i token vengono salvati automaticamente tramite la strategy. Ritorna null in caso di errore (consulta getLastError() per dettagli).
const result = await authService.login({
email: 'user@example.com',
password: 'password123',
})
if (!result) {
const err = authService.getLastError()
console.error(`[${err?.code}] ${err?.message}`)
}
logout(refreshToken: string | null): Promise<void>
Logout fail-safe: pulisce prima lo stato locale (token + cache invalidate), poi notifica il server con timeout di 5 secondi. Se la chiamata server fallisce, lo stato locale rimane pulito e l'errore e registrato in lastError.
await authService.logout(null) // usa il refreshToken corrente
refreshToken(token?, refreshToken?): Promise<AuthResponse | null>
Aggiorna i token. Implementa locking concorrente: se un refresh e gia in corso, le chiamate successive attendono il completamento del primo (evita refresh duplicati e race condition). Le richieste in attesa vengono notificate dopo 200ms dal nuovo token.
handleAuthError(error: AxiosError): Promise<boolean>
Hook IAuthHandler chiamato dal client HTTP su risposta 401. Tenta il refresh e ritorna true se la richiesta originale puo essere ritentata.
httpClient.setAuthHandler(authService)
// Ogni risposta 401 attiva refresh + retry automatico
const data = await httpClient.get('/api/protected')
Altri metodi
register(user)— registra un nuovo utente, ritornaCustomResponseactivateAccount(token)— attiva account via token emailforgotPassword({ email })— invia email di reset (risposta generica per evitare enumeration)resetPassword({ token, password })— reimposta la passwordgetToken()/getRefreshToken()— accessor diretti via strategysetTokens(token, refreshToken)— set manuale dei token (passarenull, nullper logout locale)getLastError()— ultimo errore concode,message,timestamp,details
Codici errore
Tutti gli errori vengono normalizzati in AuthError con codici:
AUTH_INVALID_RESPONSE— risposta server non conforme allo schemaAUTH_ERROR_<status>— errore HTTP con status code (es.AUTH_ERROR_401)AUTH_REFRESH_MISSING_TOKEN— manca il refresh tokenAUTH_REFRESH_INVALID_RESPONSE— refresh response non validaAUTH_REFRESH_FAILED— refresh fallito (network/server)AUTH_LOGOUT_SERVER_FAILED— logout server fallito (stato locale gia pulito)AUTH_UNKNOWN_ERROR— errore imprevisto
Factory
Per creare istanze in modo consistente con il resto del package, vedi AuthServiceFactory.
Esempio integrato
import {
HttpClientFactory,
AuthStrategyFactory,
AuthServiceFactory,
} from '@pzeta/postgrest'
const httpClient = HttpClientFactory.createFetchClient({ baseURL: '/api' })
const strategy = AuthStrategyFactory.createJwtStrategy()
const authService = AuthServiceFactory.create(httpClient, strategy)
httpClient.setAuthStrategy(strategy)
httpClient.setAuthHandler(authService)
if (!strategy.isAuthenticated()) {
await authService.login({ email, password })
}