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
- Displays the login form
- Validates that the email has the correct format and that the password is not empty
- Sends the credentials over HTTPS to the API Gateway
- Receives the tokens and stores them (usually in memory or in an httpOnly cookie)
- 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
- Receives the login request (this route does not require a prior token)
- Applies rate limiting to prevent brute-force attacks
- Logs the login attempt in the access log
- Routes to the BFF
BFF
- Receives the credentials
- Invokes the authentication service
- If authentication succeeds, transforms the response into the format the frontend expects
- 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:
- Looks up the user by email in the database
- If it does not exist, returns an invalid credentials error
- If it exists, compares the stored password hash against the received password
- 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
- 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.