Ir al contenido

Iniciar sesión con Vimine

Ver como Markdown

Los socios de una asociación inician sesión en tu sitio con su cuenta de Vimine y te autorizan, con un consentimiento explícito, a usar algunos de sus datos. Es OAuth 2.1 con PKCE: la contraseña solo se escribe en la página de Vimine, nunca en la tuya; tu sitio recibe tokens limitados a los permisos concedidos.

  1. A partir del clic de un socio, tu sitio envía el navegador (la ventana principal, nunca un iframe) a la página de autorización:
    https://app.vimine.network/authorize
    ?client_id=vmc_…&redirect_uri=https://www.example.org/vimine/callback
    &response_type=code&state=…&code_challenge=…&code_challenge_method=S256
    &scope=profile:read%20membership:read
  2. El socio inicia sesión (si no lo había hecho ya) y ve a quién concede qué. Confirma o cancela.
  3. Vimine devuelve el navegador a tu redirect_uri con code y state (o error=access_denied).
  4. Tu sitio intercambia el código en POST https://api.vimine.network/v1/oauth/token (grant_type=authorization_code, code, code_verifier, client_id, redirect_uri) y recibe un token de acceso (10 minutos) y un refresh token (rotativo; 30 días, 14 de inactividad).

El SDK hace todo esto por ti.

cualquier página
import { Vimine } from '@vimine/sdk';
const vimine = new Vimine({
clientId: 'vmc_…',
redirectUri: 'https://www.example.org/vimine/callback',
scopes: ['profile:read', 'membership:read']
});
// desde un clic: `returnTo` es tu propio estado, te lo devuelven después del callback
document.querySelector('#sign-in').addEventListener('click', () => vimine.signIn({ returnTo: location.pathname }));
página de callback
const result = await vimine.handleRedirect(); // null cuando la URL no lleva parámetros de inicio de sesión
if (result) location.replace(result.returnTo || '/');

Opciones de signIn():

Opción Efecto
scopes los permisos que se solicitan en este inicio de sesión (por defecto: los del constructor, o profile:read membership:read)
prompt: 'login' fuerza el formulario de credenciales aunque haya una sesión de Vimine activa
prompt: 'consent' muestra siempre la pantalla de consentimiento
returnTo tu propio estado (por ejemplo, la página desde la que salió el socio), guardado localmente y devuelto por handleRedirect()

handleRedirect() lanza un VimineError con code access_denied cuando el socio ha cancelado, y state_mismatch o no_flow cuando la vuelta no corresponde a un inicio de sesión empezado desde este navegador.

  • Los tokens viven en sessionStorage (por pestaña). storage: 'local' los comparte entre pestañas y sincroniza el cierre de sesión; 'memory' no los guarda nunca. Puedes pasar un adaptador propio.
  • vimine.getAccessToken() renueva solo 30 segundos antes de la caducidad; una llamada que recibe 401 se repite una vez después de la renovación. Un refresh token reutilizado (uno copiado, por ejemplo) revoca toda la familia de sesiones.
  • vimine.onChange(session => …) notifica el inicio de sesión, la renovación y el cierre de sesión.
  • vimine.getSession().sub es el identificador del socio para tu asociación (vms_…): estable en el tiempo, distinto en cada asociación, nunca un id interno.
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 }); // historial de estados
await vimine.membership.statuto(); // el estatuto en vigor y si el socio lo ha aceptado
await vimine.membership.acceptStatuto({ version: 3 }); // statuto:accept
await vimine.membership.request({ accept_statuto: { version: 3 }, privacy_notice: { version: 2 } }); // membership:request → carné pendiente
await vimine.membership.card(); // el token del carné (QR) y su ventana
await vimine.legal.acceptances(); // legal:read → lo que ha aceptado y lo que aún está pendiente
await vimine.legal.record({ kind: 'privacy_notice', version: 2 }); // legal:accept → acusa recibo de la política de la asociación
await vimine.connections.list(); await vimine.connections.revoke('vmc_…');

verdict es lo que cuenta en la entrada: valid, expired, statuto_required (ha vencido el plazo para volver a aceptar el estatuto) o inactive. Quien todavía no es socio también puede iniciar sesión y usar membership.request: el consentimiento a los permisos de inscripción también lo pueden dar quienes no son socios; los demás permisos requieren un carné en esa asociación.

Cada método se detalla en Vimine; las respuestas, en Tipos.

await vimine.signOut(); // revoca la sesión de la API y la olvida
await vimine.signOut({ everywhere: true }); // además cierra la sesión de Vimine del socio y vuelve a tu sitio

Con everywhere, el navegador pasa por https://app.vimine.network/oauth/logout?client_id=…&post_logout_redirect_uri=…; la dirección de vuelta debe estar en un origen registrado para el cliente. Cuando el socio cierra la sesión de Vimine, se revocan todas las sesiones de la API de sus apps (cierre de sesión único); lo mismo ocurre cuando revoca una app desde Apps conectadas o restablece su contraseña.

Si no puedes usar el SDK (otro lenguaje, una plataforma low-code), el flujo es OAuth 2.1 estándar.

Autorización — GET https://app.vimine.network/authorize

Parámetro
client_id tu vmc_…
redirect_uri uno de los registrados, idéntico
response_type code
state valor aleatorio, para comparar a la vuelta
code_challenge, code_challenge_method PKCE, solo S256
scope permisos separados por espacios
prompt opcional: login, consent
ui_locales opcional: uno de los idiomas de Vimine — it (por defecto), en, zh-Hans, zh-Hant, fr, es, de, pt-BR

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

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

Renovación — el mismo endpoint con grant_type=refresh_token&refresh_token=…&client_id=…: la respuesta lleva un refresh token nuevo (el antiguo sigue siendo válido 15 segundos para las peticiones concurrentes; después, reutilizarlo revoca toda la familia).

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

Descubrimiento — GET https://api.vimine.network/.well-known/oauth-authorization-server (RFC 8414) enumera los endpoints, los scopes y los métodos admitidos.

Los errores de estos endpoints usan el formato OAuth: { "error": "invalid_grant", "error_description": "…" }.