Skip to content

Repository files navigation

David Medina, Andrea Sosa y Samuel Rodríguez

OAuth2 Demo (API + Frontend)

Proyecto demo que implementa un servidor OAuth2 (grant types: password, refresh_token, client_credentials) y un frontend local para probar flujos de autenticación, refresh automático y llamadas a endpoints protegidos.

En este repo el servidor corre sobre HTTPS local (self-signed). El frontend estático se sirve desde public/ y debes usar la página frontend para las pruebas principales (es obligatorio seguir la guía del frontend). La sección de Postman está marcada como opcional.


Contenido

  • index.js — servidor Express + OAuth2 (HTTPS)
  • models/oauthModel.js, register.js, users.js, accounts.js
  • middlewares/oauthAuthenticate.js, authorizeScopes.js, AuthorizationRoles.js
  • public/auth-frontend.html — frontend de pruebas (UI, conteo de tokens, refresh automático)
  • certs/ — certificados key.pem y cert.pem (self-signed para dev)
  • package.json

Requisitos (prerequisitos)

  • Node.js >= 16 (recomendado) y npm
  • Windows / macOS / Linux (las instrucciones son cross-platform)
  • Navegador moderno (Chrome / Edge / Firefox)
  • Postman (opcional) si quieres probar la API fuera del frontend

Instalación (rápida)

  1. Clona el repo o copia los archivos al directorio del proyecto.
  2. En la raíz del proyecto ejecuta:
npm install

Esto instalará las dependencias del proyecto (express, oauth2-server, bcryptjs, dotenv, etc.).


Generar certificados HTTPS (self-signed)

Necesitamos certificados para el servidor HTTPS local. Hay dos opciones: OpenSSL o script Node (no necesita OpenSSL).

  1. Instala selfsigned como dev-dependency
npm install --save-dev selfsigned
  1. Ejecuta:
node generate-cert.js

Verifica que certs/key.pem y certs/cert.pem existen.


Iniciar el servidor

Asegúrate de tener certs/key.pem y certs/cert.pem en ./certs.

Ejecuta:

npm start

Salida esperada (ejemplo):

HTTPS Server listening on port 3443
HTTP Server listening on port 3000 and redirecting to HTTPS:3443

Configuración importante de tokens (lifetimes)

En index.js se configuró:

accessTokenLifetime: 60   // access token expira en 60 segundos (1 minuto)
refreshTokenLifetime: 120 // refresh token expira en 120 segundos (2 minutos)

Estos valores se usan en el servidor. El frontend también asume access = 60s y refresh = 120s para mostrar los contadores en tiempo real. Si cambias los valores en el servidor, actualiza las constantes del frontend (ACCESS_LIFETIME / REFRESH_LIFETIME).


Probar desde la página frontend

https://localhost:3443/auth-frontend.html

Nota: La primera vez el navegador mostrará advertencia por certificado self-signed — elige Advanced → Proceed to localhost para aceptar de forma temporal.


Flujo de prueba desde el frontend (paso a paso)

  1. Campos por defecto (prueba rápida):
  • username: admin
  • password: 1234
  • client_id: webapp
  • client_secret: websecret
  1. Click Iniciar sesión:
  • El frontend hará POST /oauth/token con grant_type=password.
  • Si OK verás Login OK y se mostrarán:
  • Access (contador MM:SS → empieza en 01:00)
  • Refresh (contador MM:SS → empieza en 02:00)
  1. Click Ver /userProfile:
  • Llama a /userProfile con Authorization: Bearer <access_token>.
  • Si el access_token expiró, el frontend intentará automáticamente refresh usando refresh_token, guardará el nuevo access_token y reintentará la petición.
  1. Click Ver /users:
  • Requiere role: admin y scope user.read. Usa admin para ver la lista completa.
  1. Click Generar token (client_credentials):
  • El frontend pedirá token con client_id=application y client_secret=secret.
  • Guarda el token de servicio y lo puedes usar para llamar /serviceInfo.
  1. Click Llamar /serviceInfo:
  • Envía el token de servicio en header y devuelve { service: 'demo', status: 'ok', client: 'application' } si el token tiene service.read.
  1. Observa los contadores:
  • Access baja en tiempo real.
  • Cuando Access llega a 00:00, la primera petición protegida devolverá 401 y el frontend intentará refresh automáticamente (si Refresh aún es válido).
  • Si Refresh llega a 00:00, el refresh fallará y tendrás que iniciar sesión de nuevo.

Endpoints principales

  • POST /oauth/token — token endpoint (grant password, refresh_token, client_credentials)
  • GET /userProfile — perfil del usuario (requiere user.read)
  • GET /users — lista de usuarios (requiere role admin y scope user.read)
  • GET /serviceInfo — endpoint demo que requiere service.read (para tokens client_credentials)

Desarrollo y debugging

  • El modelo guarda tokens en memoria (array). Revisa models/oauthModel.js y su variable tokens si quieres inspeccionar los tokens activos.
  • Logs útiles:
    • oauthModel.getAccessToken y getRefreshToken realizan console.log para facilitar debugging.
  • Para ver errores de autenticación revisa la consola donde ejecutaste npm start.

Diagramas UML

Esta sección muestra la arquitectura del proyecto OAuth2 dividida en componentes y secuencia de ejecución.

Los diagramas están escritos en PlantUML, por lo que puedes renderizarlos fácilmente en VS Code con la extensión PlantUML o en línea en https://www.plantuml.com/plantuml.


Diagrama de Componentes

Este diagrama muestra los principales módulos del sistema: el Frontend, el Servidor HTTPS, el Modelo OAuth2, los Middlewares, y los Módulos de negocio.
Permite entender cómo cada capa interactúa con las demás.

image

Diagrama de Secuencia

Describe el flujo completo del sistema:

  1. Login (password grant)
  2. Llamada a recurso protegido con token válido
  3. Token expirado → Refresh automático → Retry exitoso
image

Opcional: Probar con Postman

Si prefieres usar Postman para algunas pruebas (opcional), aquí tienes las requests principales (recuerda desactivar verificación SSL en Postman para aceptar el certificado self-signed).

  1. Password grant (obtener access + refresh)
grant_type = password
username = admin
password = 1234
client_id = webapp
client_secret = websecret
  1. Llamar endpoint protegido
  1. Refresh token
grant_type = refresh_token
refresh_token = <REFRESH_TOKEN>
client_id = webapp
client_secret = websecret
  1. Client credentials
grant_type = client_credentials
client_id = application
client_secret = secret

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages