Auth

JwtAuthStrategy

Strategia di autenticazione JWT Bearer. Token in sessionStorage di default, storage custom pluggable via interfaccia JwtTokenStorage.

Cosa fa

JwtAuthStrategy implementa l'autenticazione Bearer Token RFC 6750: aggiunge l'header Authorization: Bearer <token> a ogni richiesta HTTP. Supporta access token + refresh token con supportsRefresh() === true.

E la strategia default per @pzeta/postgrest: adatta alla maggior parte delle API REST stateless.

Quando usarla

  • API REST stateless con JWT
  • Applicazioni SPA con backend che emette accessToken + refreshToken
  • Quando il backend NON puo emettere cookie (es. dominio cross-origin senza CORS credentials)
Il token e leggibile da JavaScript (anche con sessionStorage): un XSS riesce a esfiltrarlo. Per superficie d'attacco minima preferire CookieAuthStrategy (cookie HTTP-only).

Costruttore

class JwtAuthStrategy implements IAuthStrategy {
  constructor(storage?: JwtTokenStorage)
}
ParametroTipoDefaultDescrizione
storageJwtTokenStoragenew SessionStorageJwtStorage()Storage pluggable per i token

Storage default: SessionStorageJwtStorage

class SessionStorageJwtStorage implements JwtTokenStorage {
  // chiavi: 'jwt' e 'refreshToken' in sessionStorage
}

Caratteristiche:

  • Isolato per tab del browser
  • Persiste durante la navigazione nello stesso tab
  • Eliminato alla chiusura del tab/finestra
  • Non condiviso tra tab
Scelta architetturale: la libreria adotta sessionStorage come default per limitare il blast radius XSS (token volatile e tab-scoped). Per scenari "remember me" passare uno storage custom (localStorage, in-memory, IndexedDB cifrato, ecc.).

Interfaccia JwtTokenStorage

interface JwtTokenStorage {
  getToken(): string | null
  setToken(token: string | null): void
  getRefreshToken(): string | null
  setRefreshToken(token: string | null): void
  clear(): void
}

Implementazioni alternative tipiche:

  • In-memory per test (Jest/Vitest)
  • localStorage per persistenza cross-sessione (opt-in esplicito da parte dell'app)
  • Cifrata con chiave derivata da PIN utente

Esempi

Default (sessionStorage)

import { JwtAuthStrategy } from '@pzeta/postgrest'

const strategy = new JwtAuthStrategy()
// equivalente a: new JwtAuthStrategy(new SessionStorageJwtStorage())

Storage in-memory per test

import type { JwtTokenStorage } from '@pzeta/postgrest'

class InMemoryJwtStorage implements JwtTokenStorage {
  private token: string | null = null
  private refresh: string | null = null

  getToken() { return this.token }
  setToken(t: string | null) { this.token = t }
  getRefreshToken() { return this.refresh }
  setRefreshToken(t: string | null) { this.refresh = t }
  clear() { this.token = null; this.refresh = null }
}

const strategy = new JwtAuthStrategy(new InMemoryJwtStorage())

Override storage con localStorage (persistenza)

class LocalStorageJwtStorage implements JwtTokenStorage {
  getToken() { return localStorage.getItem('jwt') }
  setToken(t: string | null) {
    t === null ? localStorage.removeItem('jwt') : localStorage.setItem('jwt', t)
  }
  getRefreshToken() { return localStorage.getItem('refreshToken') }
  setRefreshToken(t: string | null) {
    t === null
      ? localStorage.removeItem('refreshToken')
      : localStorage.setItem('refreshToken', t)
  }
  clear() {
    localStorage.removeItem('jwt')
    localStorage.removeItem('refreshToken')
  }
}

const strategy = new JwtAuthStrategy(new LocalStorageJwtStorage())

Comportamento

  • applyAuth(config) — aggiunge header Authorization: Bearer <token> se presente, imposta withCredentials: false (JWT non richiede cookie)
  • isAuthenticated()true se lo storage contiene un access token
  • saveCredentials(authResponse) — salva token + refreshToken
  • clearCredentials() — chiama storage.clear() (logout)
  • supportsRefresh() — sempre true

Vedi anche