Login flow

End-to-end authentication flow: from the frontend form, through the BFF and the Auth service, to the issuing of the JWT and the response to the client.

Why login is a key flow

Login is probably the first flow that any user runs in an application. It is also one of the most sensitive: it involves credentials, security tokens, and access decisions that affect the entire system.

Understanding how login flows through the architecture helps you see how the layers work together to solve a real use case from start to finish.

The flow step by step

sequenceDiagram
    participant U as Usuario
    participant FE as Frontend
    participant GW as API Gateway
    participant BFF as BFF
    participant AUTH as Auth Service
    participant DB as Users DB

    U->>FE: Ingresa email y contraseña
    FE->>FE: Validación básica del formulario
    FE->>GW: POST /auth/login
    GW->>GW: Rate limiting, logging
    GW->>BFF: Forward request
    BFF->>AUTH: Verificar credenciales
    AUTH->>DB: Buscar usuario por email
    DB-->>AUTH: Datos del usuario
    AUTH->>AUTH: Verificar hash de contraseña
    AUTH->>AUTH: Generar JWT (access + refresh)
    AUTH-->>BFF: Tokens + datos básicos del usuario
    BFF-->>GW: Respuesta formateada para UI
    GW-->>FE: 200 OK + tokens
    FE->>FE: Almacenar tokens, redirigir
    U->>FE: Ve el dashboard

What each layer does

Frontend

  1. Displays the login form
  2. Validates that the email has the correct format and that the password is not empty
  3. Sends the credentials over HTTPS to the API Gateway
  4. Receives the tokens and stores them (usually in memory or in an httpOnly cookie)
  5. Redirects the user to the main page

Important: the frontend never stores the password. It only sends it once and works with tokens from that point on.

API Gateway

  1. Receives the login request (this route does not require a prior token)
  2. Applies rate limiting to prevent brute-force attacks
  3. Logs the login attempt in the access log
  4. Routes to the BFF

BFF

  1. Receives the credentials
  2. Invokes the authentication service
  3. If authentication succeeds, transforms the response into the format the frontend expects
  4. If it fails, returns a generic error (without revealing whether the email exists or not)

Auth Service

This is the microservice specialized in identity and access:

  1. Looks up the user by email in the database
  2. If it does not exist, returns an invalid credentials error
  3. If it exists, compares the stored password hash against the received password
  4. If they match, generates a pair of JWT tokens:
    • Access token: short-lived (15–30 minutes), contains the user’s claims
    • Refresh token: longer-lived (7–30 days), allows renewing the access token
  5. Returns the tokens and basic user data (name, role, permissions)

Users database

Stores the user’s data including:

  • Email (unique)
  • Password hash (never the password in plain text)
  • Role and permissions
  • Account status (active, locked, pending verification)
  • Metadata (last login, failed attempts)

JWT structure

The JWT access token typically contains:

{
  "header": {
    "alg": "RS256",
    "typ": "JWT"
  },
  "payload": {
    "sub": "user-123",
    "email": "usuario@ejemplo.com",
    "role": "admin",
    "permissions": ["read:orders", "write:orders"],
    "iat": 1705312200,
    "exp": 1705314000,
    "iss": "auth-service"
  }
}

The token is signed with a private key that only the Auth Service knows. Any service can verify the signature with the corresponding public key.

Token refresh flow

When the access token expires, the frontend uses the refresh token to obtain a new one without asking for credentials again:

sequenceDiagram
    participant FE as Frontend
    participant GW as API Gateway
    participant BFF as BFF
    participant AUTH as Auth Service

    FE->>GW: POST /auth/refresh (refresh token)
    GW->>BFF: Forward
    BFF->>AUTH: Validar refresh token
    AUTH->>AUTH: Verificar firma y expiración
    AUTH->>AUTH: Generar nuevo access token
    AUTH-->>BFF: Nuevo access token
    BFF-->>GW: Respuesta
    GW-->>FE: 200 OK + nuevo access token

Error scenarios

Incorrect credentials

The Auth Service returns a generic error: “Invalid credentials”. It does not indicate whether the email exists or not, to avoid user enumeration.

Locked account

After N failed attempts (typically 5), the account is temporarily locked. The service returns an error indicating that the account is locked and when it can be retried.

Expired token

The frontend detects a 401 on any subsequent request and automatically tries to renew the token with the refresh token. If the refresh token has also expired, it redirects to the login.

Auth service unavailable

If the Auth Service is down, the BFF returns a 503. The frontend shows a “service temporarily unavailable” message and allows the user to retry.

Security considerations

  • Passwords are transmitted only over HTTPS
  • They are stored as a salted hash (bcrypt, argon2)
  • Tokens have a short expiration
  • The refresh token can be revoked from the server
  • Rate limiting protects against brute force
  • Errors do not reveal information about the existence of accounts

Summary

The login flow demonstrates how all the layers of the architecture work together to solve a critical use case. Each layer has a clear responsibility: the frontend handles the user experience, the Gateway protects the entry point, the BFF orchestrates and transforms, and the Auth Service manages identity. Security is not an afterthought but an integral part of the flow’s design.