RF03: Usuario inicia sesión con Google
Descripción
Como usuario, quiero iniciar sesión con mi cuenta de Google para acceder a Finnova sin recordar otra contraseña.
Google Sign-In solo autentica la identidad: la app obtiene un ID Token firmado por Google, el backend lo verifica contra las claves públicas de Google y, si es válido, identifica o crea al usuario y emite sus propios tokens de Finnova. Toda la integración está definida en Login con Google en la App Móvil.
| Campo | Valor |
|---|---|
| Módulo | Auth Module |
| Actor | Usuario (registrado o nuevo) |
| Endpoint | POST /auth/google |
| Precondiciones | La app obtuvo un ID Token válido vía el SDK de Google |
| Prioridad | Alta (MVP) |
| Etapa | MVP |
| Requisitos relacionados | RF01, RF02, RF04 |
Reglas de negocio
- RN-03.1 — El backend siempre verifica el ID Token con
google-auth-library, validando firma,audience(Web Client ID),issuery expiración. Nunca confía en datos del cliente sin validar. - RN-03.2 — El usuario se identifica por
google_sub(estable e inmutable), no por email. - RN-03.3 — Account linking: si
google_subes nuevo pero el email ya existe y está verificado (email_verified: true), se vincula a la cuenta existente; si todo es nuevo, se crea cuenta sin contraseña (ver §6 de la integración). - RN-03.4 — A partir de la verificación, el flujo de sesión es idéntico al de RF02 (se crea fila en
sessions, se emiten tokens, aplican límites por plan). - RN-03.5 — El ID Token de Google no se almacena; se usa una vez y se descarta.
Validaciones de entrada
| Campo | Reglas | Mensaje de error |
|---|---|---|
id_token | Obligatorio. JWT verificable contra Google. | "No se pudo iniciar sesión con Google. Intenta de nuevo." |
deviceInfo | Obligatorio. | — |
No se aceptan tokens cuyo
audienceno corresponda a Finnova ni cuyoemail_verifiedseafalseal vincular por email.
Criterios de aceptación
Escenario 1: Login con Google exitoso — usuario existente
Dado que ya tengo una cuenta con google_sub registrado,
Cuando la app envía un ID Token válido,
Entonces el backend lo verifica, me identifica por google_sub,
Y crea una sesión y devuelve access_token + refresh_token con 200 OK.
Escenario 2: Primer login con Google — cuenta nueva
Dado que mi google_sub y mi email no existen en Finnova,
Cuando envío un ID Token válido,
Entonces el sistema crea una cuenta nueva (sin contraseña) con email, nombre y google_sub,
Y me autentica con 201 Created.
Escenario 3: Vinculación a cuenta existente por email
Dado que me registré antes con correo/contraseña usando ana@gmail.com y ahora uso "Continuar con Google" con el mismo correo verificado,
Cuando el backend verifica el token,
Entonces añade google_sub a mi cuenta existente (account linking),
Y me autentica sin crear cuenta duplicada.
Escenario 4: Token inválido o de otra app (seguridad)
Dado que llega un ID Token expirado, con firma inválida o audience distinto al de Finnova,
Cuando el backend lo verifica,
Entonces rechaza la solicitud con 401 Unauthorized,
Y no crea usuario ni sesión.
Escenario 5: Email de Google no verificado
Dado que el ID Token trae email_verified: false y el email coincide con una cuenta existente,
Cuando el backend procesa el login,
Entonces no vincula automáticamente por email,
Y responde con error pidiendo verificar la cuenta.
Criterios no funcionales
- El backend valida el token con las claves públicas de Google (cacheadas).
- Comunicación sobre TLS 1.2+.
- El ID Token no se persiste ni se registra en logs.