Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/interezante456-pixel/Miercoles-Proyecto/llms.txt

Use this file to discover all available pages before exploring further.

Tiendas Mi Cholo utiliza JSON Web Tokens (JWT) firmados con el algoritmo HMAC-SHA256 para autenticar todas las peticiones a la API. El sistema es completamente stateless: el servidor no almacena sesiones; en cambio, cada petición debe incluir un token válido en el header Authorization. Al hacer login recibirás dos tokens: un access token de corta duración para las peticiones del día a día, y un refresh token de larga duración para renovarlo sin necesidad de volver a ingresar credenciales.

Rutas públicas (sin autenticación)

Las siguientes rutas no requieren token y son accesibles para cualquier cliente:
RutaMétodos
/api/auth/**Todos
/api/actuator/**Todos
Todos los demás endpoints del sistema requieren un token JWT válido en el header Authorization.

Cómo iniciar sesión

POST /api/auth/login

Envía las credenciales del usuario para obtener los tokens JWT. URL: http://localhost:8080/api/auth/login
Autenticación requerida: No
Content-Type: application/json

Campos de la petición

username
string
required
Nombre de usuario registrado en el sistema (por ejemplo: admin, jperez, mgarcia).
password
string
required
Contraseña del usuario. Mínimo 6 caracteres. Se verifica contra el hash BCrypt almacenado en la base de datos.

Ejemplo con cURL

curl -s -X POST http://localhost:8080/api/auth/login \
  -H "Content-Type: application/json" \
  -d '{
    "username": "admin",
    "password": "admin123"
  }'

Ejemplo con JavaScript Fetch

const response = await fetch('http://localhost:8080/api/auth/login', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    username: 'admin',
    password: 'admin123'
  })
});

const data = await response.json();
console.log(data.token);       // Access token JWT
console.log(data.refreshToken); // Refresh token JWT
console.log(data.rol);          // "ADMIN" | "VENDEDOR" | "ALMACENERO"

Campos de la respuesta 200 OK

token
string
Access token JWT firmado con HMAC-SHA256. Incluye en el header Authorization: Bearer <token> en cada petición protegida. Válido por 24 horas (app.jwt.expiration=86400000 ms).
refreshToken
string
Refresh token JWT para renovar el access token sin requerir nuevas credenciales. Válido por 7 días (app.jwt.refresh-expiration=604800000 ms).
username
string
Nombre de usuario con el que se autenticó.
nombre
string
Nombre de pila del usuario autenticado.
apellido
string
Apellido del usuario autenticado.
email
string
Correo electrónico del usuario autenticado.
rol
string
Rol asignado al usuario: ADMIN, VENDEDOR o ALMACENERO.

Respuesta de ejemplo 200 OK

{
  "token": "eyJhbGciOiJIUzI1NiJ9.eyJyb2xlcyI6WyJST0xFX0FETUlOIl0...",
  "refreshToken": "eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJhZG1pbiJ9...",
  "username": "admin",
  "nombre": "Admin",
  "apellido": "Sistema",
  "email": "admin@tienda.com",
  "rol": "ADMIN"
}

Los dos tokens: acceso y refresco

El sistema emite dos tokens distintos con propósitos y duraciones diferentes:
TokenClaim principalDuraciónUso
Access token (token)subject (username) + roles24 horas (86 400 000 ms)Autenticar cada petición protegida
Refresh token (refreshToken)subject (username)7 días (604 800 000 ms)Renovar el access token expirado
El access token incluye los siguientes claims JWT:
  • subusername del usuario
  • roles — lista de roles, por ejemplo ["ROLE_ADMIN"]
  • iat — timestamp de emisión
  • exp — timestamp de expiración

Cómo usar el token en cada petición

Incluye el access token en el header HTTP Authorization con el esquema Bearer:
Authorization: Bearer <access_token>

Ejemplo con cURL

curl -s http://localhost:8080/api/dashboard/stats \
  -H "Authorization: Bearer eyJhbGciOiJIUzI1NiJ9..."

Ejemplo con JavaScript Fetch

const TOKEN_KEY = 'tienda_token';
const token = localStorage.getItem(TOKEN_KEY);

const response = await fetch('http://localhost:8080/api/dashboard/stats', {
  method: 'GET',
  headers: {
    'Authorization': `Bearer ${token}`,
    'Content-Type': 'application/json'
  }
});

const stats = await response.json();
console.log(stats);

Ejemplo con Angular HttpClient

El frontend de Tiendas Mi Cholo utiliza un HTTP interceptor que adjunta automáticamente el token a todas las peticiones salientes. La clave de almacenamiento en localStorage es tienda_token.
// auth.interceptor.ts
import { HttpInterceptorFn } from '@angular/common/http';

const TOKEN_KEY = 'tienda_token';

export const authInterceptor: HttpInterceptorFn = (req, next) => {
  const token = localStorage.getItem(TOKEN_KEY);

  if (token) {
    const authReq = req.clone({
      setHeaders: {
        Authorization: `Bearer ${token}`
      }
    });
    return next(authReq);
  }

  return next(req);
};
// Uso directo en un servicio Angular
import { HttpClient, HttpHeaders } from '@angular/common/http';
import { Injectable } from '@angular/core';

@Injectable({ providedIn: 'root' })
export class DashboardService {
  private readonly API = 'http://localhost:8080/api';
  private readonly TOKEN_KEY = 'tienda_token';

  constructor(private http: HttpClient) {}

  getStats() {
    const token = localStorage.getItem(this.TOKEN_KEY);
    const headers = new HttpHeaders({
      Authorization: `Bearer ${token}`
    });
    return this.http.get(`${this.API}/dashboard/stats`, { headers });
  }
}

Matriz de permisos por módulo y rol

La siguiente tabla muestra qué operaciones puede realizar cada rol en cada módulo de la API:
MóduloOperaciónADMINVENDEDORALMACENERO
AuthLogin
UsuariosCRUD completo
RolesListar
CategoríasListar / Ver
CategoríasCrear / Editar / Eliminar
ProductosListar / Ver / Buscar
ProductosCrear / Editar
ProductosEliminar
ClientesCRUD completo
ProveedoresCRUD completo
VentasListar / Ver
VentasRegistrar
VentasAnular
ComprasListar / Ver
ComprasCrear / Recibir
InventarioListar
DashboardStats
ReportesPDF Ventas / Inventario

Respuestas de error de autenticación

401 Unauthorized — Token ausente, inválido o expirado

Se devuelve cuando el header Authorization está ausente, el token tiene una firma inválida, o el token ha expirado.
{
  "timestamp": "2024-01-15T10:30:00.123",
  "status": 401,
  "error": "Credenciales inválidas"
}
Causas comunes:
  • No se envió el header Authorization
  • El token fue manipulado (firma HMAC inválida)
  • Han transcurrido más de 24 horas desde la emisión del access token
  • Se usó el refresh token en lugar del access token para una petición de recurso

403 Forbidden — Rol insuficiente

Se devuelve cuando el token es válido pero el rol del usuario no tiene permiso para realizar la operación solicitada.
{
  "timestamp": "2024-01-15T10:30:00.123",
  "status": 403,
  "error": "Acceso denegado: rol insuficiente para esta operación"
}
Ejemplo: Un usuario con rol VENDEDOR que intenta acceder a GET /api/usuarios (exclusivo de ADMIN) recibirá un 403 Forbidden.
Seguridad del token: El frontend de Tiendas Mi Cholo almacena el access token en localStorage bajo la clave tienda_token. Este almacenamiento es conveniente para SPAs pero es vulnerable a ataques XSS (Cross-Site Scripting). Para entornos de producción, considera las siguientes medidas:
  • Sanitiza siempre el contenido renderizado dinámicamente en Angular.
  • Implementa una Content Security Policy (CSP) estricta en el servidor.
  • Evalúa migrar a cookies HttpOnly + SameSite=Strict para mayor seguridad en producción.
  • Nunca expongas el app.jwt.secret en repositorios públicos; usa variables de entorno o un gestor de secretos.

Build docs developers (and LLMs) love