Salta ai contenuti

Accedi con Vimine

Apri come Markdown

I soci di un’associazione accedono al tuo sito con il loro account Vimine e ti autorizzano, con un consenso esplicito, a usare alcuni loro dati. È OAuth 2.1 con PKCE: la password viene inserita solo sulla pagina di Vimine, mai sulle tue; il tuo sito riceve token limitati ai permessi concessi.

  1. Da un click del socio, il tuo sito porta il browser (la finestra principale, mai un iframe) alla pagina di autorizzazione:
    https://app.vimine.network/authorize
    ?client_id=vmc_…&redirect_uri=https://www.tuosito.it/vimine/callback
    &response_type=code&state=…&code_challenge=…&code_challenge_method=S256
    &scope=profile:read%20membership:read
  2. Il socio accede (se non lo è già) e vede a chi sta concedendo cosa. Conferma o annulla.
  3. Vimine rimanda il browser al tuo redirect_uri con code e state (oppure error=access_denied).
  4. Il tuo sito scambia il codice con POST https://api.vimine.network/v1/oauth/token (grant_type=authorization_code, code, code_verifier, client_id, redirect_uri) e riceve un access token (10 minuti) e un refresh token (rotante; 30 giorni, 14 di inattività).

L’SDK fa tutto questo per te.

La pagina resta di Vimine (l’indirizzo, il logotipo, le parole e i controlli sono i suoi), ma mostra la tua associazione: a sinistra, o in alto su un telefono, il suo logo e il suo nome, il nome della tua app e il sito a cui il socio torna, cioè l’host del tuo redirect_uri.

In Sviluppatori › la tua app › Aspetto scegli:

  • un colore: tinge la metà dell’associazione e sfuma in quella di Vimine; sulla scheda di accesso colora solo il pulsante principale e i link, scurito o schiarito finché si legge;
  • un carattere, tra quelli che Vimine serve da sé, per la metà dell’associazione.

Chiaro o scuro, e la tavolozza, li decide il socio: quelli che ha scelto in Vimine su quel dispositivo, altrimenti la tavolozza di Vimine nel chiaro o nello scuro del suo browser. Per questo l’anteprima mostra le due versioni e l’indirizzo di autorizzazione non ne porta nessuna.

Se il logo dell’associazione è fatto per uno sfondo solo, indicalo in Associazione › Scheda › Logo pensato per: sull’altro schema la pagina lo mette su un riquadro.

pagina qualsiasi
import { Vimine } from '@vimine/sdk';
const vimine = new Vimine({
clientId: 'vmc_…',
redirectUri: 'https://www.tuosito.it/vimine/callback',
scopes: ['profile:read', 'membership:read']
});
// da un click: `returnTo` è un tuo stato, lo ritrovi dopo il callback
document.querySelector('#accedi').addEventListener('click', () => vimine.signIn({ returnTo: location.pathname }));
pagina di callback
const result = await vimine.handleRedirect(); // null se l'URL non ha i parametri di un accesso
if (result) location.replace(result.returnTo || '/');

Opzioni di signIn():

Opzione Effetto
scopes i permessi da chiedere in questo accesso (default: quelli del costruttore, o profile:read membership:read)
prompt: 'login' obbliga a reinserire le credenziali anche con una sessione Vimine viva
prompt: 'consent' mostra sempre la schermata di consenso
returnTo uno stato tuo (per esempio la pagina di partenza), conservato in locale e restituito da handleRedirect()

handleRedirect() lancia un VimineError con code access_denied se il socio ha annullato, state_mismatch o no_flow se il ritorno non corrisponde a un accesso avviato da questo browser.

  • I token stanno in sessionStorage (per scheda). storage: 'local' li condivide tra schede e sincronizza l’uscita; 'memory' non li salva. Puoi passare un adapter tuo.
  • vimine.getAccessToken() rinnova da solo 30 secondi prima della scadenza; una chiamata che riceve 401 viene ritentata una volta dopo il rinnovo. Un refresh token riusato (per esempio copiato) revoca l’intera famiglia di sessioni.
  • vimine.onChange(session => …) notifica accesso, rinnovo e uscita.
  • vimine.getSession().sub è l’identificativo del socio per la tua associazione (vms_…): stabile nel tempo, diverso in ogni associazione, mai un id interno.
  • vimine.getSession().aps è l’associazione in cui il socio ha fatto l’accesso (slug, name, picture_url): per mostrarne nome e logo accanto al socio senza un’altra chiamata.
await vimine.me.get(); // profile:read
await vimine.me.update({ phone: '+39 …' }); // profile:write
await vimine.membership.get(); // membership:read — status, verdict, expires_at, statuto, card
await vimine.membership.events({ limit: 20 }); // storico degli stati
await vimine.membership.statuto(); // lo statuto in vigore e se il socio l'ha accettato
await vimine.membership.acceptStatuto({ version: 3 }); // statuto:accept
await vimine.membership.request({ accept_statuto: { version: 3 }, privacy_notice: { version: 2 } }); // membership:request → tessera in attesa
await vimine.membership.card(); // il token della tessera (QR) e la sua finestra
await vimine.legal.acceptances(); // legal:read → cosa ha accettato e cosa è ancora da confermare
await vimine.legal.record({ kind: 'privacy_notice', version: 2 }); // legal:accept → presa visione dell'informativa ai soci
await vimine.connections.list(); await vimine.connections.revoke('vmc_…');

verdict è ciò che conta allo scanner: valid, expired, statuto_required (riaccettazione scaduta) o inactive. Chi non è ancora socio può comunque accedere e usare membership.request: il consenso ai permessi di iscrizione è consentito anche ai non soci; gli altri permessi richiedono una tessera in quell’associazione.

Il dettaglio di ogni metodo è in Vimine; le risposte in Tipi.

await vimine.signOut(); // revoca la sessione API e la dimentica
await vimine.signOut({ everywhere: true }); // in più chiude la sessione Vimine del socio e torna al tuo sito

Con everywhere il browser passa da https://app.vimine.network/oauth/logout?client_id=…&post_logout_redirect_uri=…; l’indirizzo di ritorno deve stare su un’origine registrata per il client. Quando il socio esce da Vimine, tutte le sessioni API delle sue app vengono revocate (single sign-out); lo stesso quando revoca un’app da App collegate o reimposta la password.

Se non puoi usare l’SDK (un altro linguaggio, una piattaforma low-code) il flusso è OAuth 2.1 standard.

Autorizzazione — GET https://app.vimine.network/authorize

Parametro
client_id il tuo vmc_…
redirect_uri uno di quelli registrati, identico
response_type code
state valore casuale, da confrontare al ritorno
code_challenge, code_challenge_method PKCE, solo S256
scope permessi separati da spazio
prompt opzionale: login, consent
ui_locales opzionale: una delle lingue di Vimine — it (default), en, zh-Hans, zh-Hant, fr, es, de, pt-BR

Scambio — POST https://api.vimine.network/v1/oauth/token, corpo application/x-www-form-urlencoded:

grant_type=authorization_code&code=…&code_verifier=…&client_id=vmc_…&redirect_uri=…
risposta
{ "access_token": "…", "token_type": "Bearer", "expires_in": 600, "refresh_token": "…",
"scope": "profile:read membership:read", "sub": "vms_…" }

Rinnovo — stesso endpoint con grant_type=refresh_token&refresh_token=…&client_id=…: la risposta porta un nuovo refresh token (il vecchio resta valido 15 secondi per le richieste concorrenti, poi un suo riuso revoca tutta la famiglia).

Revoca — POST /v1/oauth/revoke con token=…&token_type_hint=refresh_token (RFC 7009).

Discovery — GET https://api.vimine.network/.well-known/oauth-authorization-server (RFC 8414) elenca endpoint, scope e metodi supportati.

Gli errori di questi endpoint sono nel formato OAuth: { "error": "invalid_grant", "error_description": "…" }.