swagger-docs-basic-auth-middleware
v1.1.0
Published
Reusable Express middleware to protect Swagger docs with basic auth and cookie session.
Readme
swagger-docs-basic-auth-middleware
Middleware reutilizable para proteger Swagger Docs con:
Login HTML para
/docsCookie HttpOnly de sesion
Fallback Basic Auth para otras rutas protegidas
https://www.npmjs.com/package/swagger-docs-basic-auth-middleware?activeTab=readme
Instalacion
npm install swagger-docs-basic-auth-middlewareUso rapido (Express)
import express from "express";
import { createSwaggerDocsAuthMiddleware } from "swagger-docs-basic-auth-middleware";
const app = express();
app.use(express.urlencoded({ extended: false }));
const swaggerAuth = createSwaggerDocsAuthMiddleware({
credentials: {
username: process.env.SWAGGER_USER ?? "",
password: process.env.SWAGGER_PASSWORD ?? "",
},
serverPath: process.env.SERVER_PATH,
docsPath: "/docs",
branding: {
appName: "Gateway Docs",
},
});
app.use("/docs", swaggerAuth);API
createSwaggerDocsAuthMiddleware(options: SwaggerDocsAuthOptions): RequestHandlerOpciones principales:
credentials.username: usuario requeridocredentials.password: clave requeridaserverPath: prefijo global (ej./gateway)docsPath: por defecto/docscookieName: por defectoswagger_docs_authlogger.debug/error: adaptador de logs opcionalbranding: textos y assets del login
Opciones de branding
Puedes personalizar completamente los textos y assets del formulario de login con branding.
branding?: {
appName?: string;
loginTitle?: string;
loginSubtitle?: string;
loginErrorMessage?: string;
usernameLabel?: string;
passwordLabel?: string;
submitButtonLabel?: string;
faviconHref?: string;
logoHref?: string;
}Valores por defecto:
appName:DocsloginTitle:Acceder a DocsloginSubtitle:Autenticacion requerida para la documentacion.loginErrorMessage:Credenciales invalidas. Intenta nuevamente.usernameLabel:Nombre de usuariopasswordLabel:ContrasenasubmitButtonLabel:EntrarfaviconHref: sin valor por defecto (si no se define, no se renderiza favicon)logoHref: sin valor por defecto (si no se define, no se renderiza logo)
Ejemplo completo de personalizacion:
const swaggerAuth = createSwaggerDocsAuthMiddleware({
credentials: {
username: process.env.SWAGGER_USER ?? "",
password: process.env.SWAGGER_PASSWORD ?? "",
},
docsPath: "/docs",
branding: {
appName: "Portal Tecnico",
loginTitle: "Ingresar a Swagger",
loginSubtitle: "Solo personal autorizado.",
loginErrorMessage: "Usuario o contrasena incorrectos.",
usernameLabel: "Usuario",
passwordLabel: "Clave",
submitButtonLabel: "Iniciar sesion",
faviconHref: "/assets/favicon.png",
logoHref: "/assets/logo.svg",
},
});Vista rapida del resultado
Sin branding personalizado:
- Titulo: Acceder a Docs
- Subtitulo: Autenticacion requerida para la documentacion.
- Labels: Nombre de usuario / Contrasena
- Boton: Entrar
Con branding personalizado:
- Titulo: el que definas en
loginTitle - Subtitulo: el que definas en
loginSubtitle - Labels: los que definas en
usernameLabelypasswordLabel - Boton: el que definas en
submitButtonLabel - Identidad visual:
logoHref,faviconHrefyappName
Preset recomendado para entorno corporativo:
branding: {
appName: 'Portal Interno',
loginTitle: 'Acceso a Documentacion',
loginSubtitle: 'Requiere credenciales corporativas.',
loginErrorMessage: 'Credenciales invalidas.',
usernameLabel: 'Usuario corporativo',
passwordLabel: 'Contrasena corporativa',
submitButtonLabel: 'Ingresar',
faviconHref: '/assets/corp-favicon.png',
logoHref: '/assets/corp-logo.svg'
}Troubleshooting
No carga logo o favicon
Sintoma:
- El formulario aparece, pero el logo esta roto o no se ve el favicon.
Causa comun:
logoHrefofaviconHrefapuntan a rutas que no estan siendo servidas por tu app.
Nota:
- Si no defines estos campos, el middleware no intenta cargar ningun asset por defecto.
Solucion:
- Verifica que esos archivos existan y se puedan abrir desde el navegador.
- Si usas NestJS, sirve assets estaticos (por ejemplo con
ServeStaticModule) o apunta a una URL publica. - Si tienes
serverPath, valida que la ruta final no quede duplicada o incompleta.
Ejemplo:
- Con
serverPath: '/api', el default intenta usar/api/static/images/....
Muestra JSON 401 y no formulario HTML
Sintoma:
- Respuesta:
{"statusCode":401,"message":"Authentication required."}
Causa comun:
docsPathno coincide con la ruta protegida enapp.use(...)oforRoutes(...).
Solucion:
- Alinea ambas rutas exactamente.
- Si Swagger esta en
/api/docs, usadocsPath: '/api/docs'y protege/api/docs.
Login correcto pero redirecciona a ruta inesperada
Sintoma:
- Ingresas credenciales validas y redirige a una ruta distinta a la esperada.
Causa comun:
- El
nextenviado no pertenece aldocsPathconfigurado y se sanea automaticamente.
Solucion:
- Asegura que el endpoint y assets de Swagger cuelguen de
docsPath. - Usa un
docsPathunico y consistente para todo el modulo.
El cookie no persiste en HTTPS/proxy
Sintoma:
- Te autenticas, pero al siguiente request vuelve a pedir login.
Causa comun:
- Proxy o balanceador no propaga correctamente
x-forwarded-proto: https.
Solucion:
- Configura tu proxy para enviar
x-forwarded-proto. - Verifica en network del navegador que el
Set-Cookiellegue y no sea bloqueado.
Desarrollo local
npm install
npm run build
npm run testDemo local (login en navegador)
Puedes levantar un servidor demo dentro de este repositorio para probar el formulario de login.
npm install
npm run demo:localAbre:
- http://localhost:3030/docs
Credenciales por defecto:
- Usuario:
admin - Contrasena:
admin123
Opcionalmente puedes cambiarlo con variables de entorno:
SWAGGER_USER=miusuario SWAGGER_PASSWORD=miclave PORT=3030 npm run demo:localPublicar en npm
- Actualiza version en
package.json. - Inicia sesion:
npm login- Publica:
npm publish --access publicSi publicas en un registro privado, ajusta .npmrc y usa el scope correspondiente.
