TutuId

Guía de integración

Añade «Iniciar con Tutu» a tu producto en cuatro pasos con OAuth2 + PKCE.

Cuatro pasos para integrar

1

El frontend inicia el login

Crea una instancia con createTutuId({ baseUrl, clientId }) de @tutu/id-sdk y llama a idSdk.startLogin() al hacer clic. El SDK genera un par PKCE y redirige a la página de autorización de TutuId.

2

El usuario autoriza en TutuId

En la pantalla de consentimiento /oauth/authorize el usuario pulsa «Permitir» (se omite si ya autorizó). Tras validar client_id y la lista blanca de redirect_uri, TutuId vuelve a tu /auth/callback con un código de autorización.

3

La página de callback obtiene el code

En /auth/callback llama a idSdk.completeCallback() para obtener { code, codeVerifier }. Pasa esos dos valores a tu propio backend; nunca intercambies el token directamente en el navegador.

4

El backend intercambia el token → crea la cuenta

Tu backend intercambia code + codeVerifier por un access_token, llama a /userinfo para obtener { sub, email, emailVerified, ... }, mapea o crea una cuenta local por sub y luego emite tu propia sesión.

★ Defensa contra apropiación de cuentas (obligatorio)

Tu backend solo puede vincular o crear una cuenta local por sub (el ID único de cuenta). Solo cuando emailVerified === true puedes vincular una cuenta local existente por correo; si no, crea una cuenta aparte y deja el correo vacío.

Por qué: un atacante podría preregistrar una cuenta Tutu con el correo de una víctima; fusionar por un correo no verificado entregaría la cuenta local de la víctima. Es una línea roja de nivel CVE.

Referencia de la API del SDK

@tutu/id-sdk · totalmente del lado del cliente, sin dependencias (requiere Web Crypto + sessionStorage).

createTutuId({ baseUrl, clientId, redirectUri? })

Crea una instancia del SDK. redirectUri por defecto es ${location.origin}/auth/callback, adaptándose a dev/prod.

startLogin(scope?)

Genera un par PKCE y redirige a la página de autorización, iniciando «Iniciar con Tutu».

trySilentLogin(scope?)

Inicio silencioso: si hay sesión central y autorización previa, intercambia un código sin fricción; si no, vuelve al estado de sesión cerrada de inmediato (sin interrumpir al usuario).

completeCallback()

Analiza el resultado en la página de callback: en éxito devuelve { code, codeVerifier }, en fallo/cancelación devuelve { error }.

logoutEverywhere(returnTo?)

Cierra la sesión central, propagando el cierre a todos los productos de la suite, y luego vuelve a returnTo.

¿Quieres verlo en acción primero?