Autenticación y Admin
Configura roles de administrador de solo lectura y lectura/escritura, protege las APIs de admin y entiende el flujo de autenticación del template.
Autenticación y Admin
Este template usa Better Auth + Drizzle. El control de acceso (RBAC) se basa en la base de datos, sin elevación por variables de entorno.
Conceptos básicos: autenticación vs autorización
- Autenticación: prueba quién eres (registro/inicio de sesión). El resultado es una sesión.
- Autorización: decide qué puedes hacer después de iniciar sesión. Aquí lo controla el campo
role
en la tablausers
.
Roles:
user
— por defecto para todos.admin_ro
— solo lectura (ver datos de admin, sin escribir).admin_rw
— lectura + escritura (incluye otorgar créditos y otras acciones admin).
Una analogía sencilla
En un aeropuerto, mostrar tu identificación en seguridad es autenticación (probar identidad). Presentar la tarjeta de embarque en la puerta es autorización (verificar que puedes subirte a ese vuelo).
Comparación rápida
Tema | Autenticación | Autorización |
---|---|---|
Propósito | Verificar identidad (quién) | Verificar permisos (qué) |
Momento | Antes de la autorización | Después de autenticación exitosa |
Entradas típicas | Credenciales (contraseña, enlace por email, social) | Políticas/roles (user , admin_ro , admin_rw ) |
Salida | Sesión/identidad | Acciones permitidas y rutas protegidas |
Estándares (generales) | OIDC, ID Tokens | OAuth 2.0, scopes |
En este template: usamos cookies de sesión HttpOnly en el servidor (no tokens en el front) y un rol en la BD para los checks de autorización.
¿Qué es Better Auth?
Una librería de auth ligera y orientada a TypeScript para Next.js.
- Almacenamiento: Drizzle ORM + Postgres (ver
src/lib/auth.ts
). - Modelo de datos:
users
,sessions
,accounts
,verifications
(versrc/db/schema.ts
). - Sesiones: cookie HttpOnly y registro en
sessions
; las rutas del servidor leen la sesión conauth.api.getSession({ headers })
. - Campos extra: exponemos
uuid
yrole
en la sesión víaadditionalFields
para facilitar validaciones en servidor.
Secretos y URLs (nivel inicial)
BETTER_AUTH_SECRET
: secreto largo y aleatorio del servidor para firmar/verificar cookies/JSON Web Tokens. Genera una vez y mantenlo privado.- Generar:
openssl rand -base64 32
- Rotación: cambiarlo cierra la sesión de todos los usuarios (las sesiones previas dejan de ser válidas).
- Generar:
BETTER_AUTH_URL
: base URL del servidor usada por la librería de auth (normalmente la URL del sitio).NEXT_PUBLIC_AUTH_BASE_URL
: base del lado del cliente (en la mayoría de casos, igual que la del sitio).- Cookies
HttpOnly
ysecure
en producción (veradvanced.defaultCookieAttributes
ensrc/lib/auth.ts
).
Si ves que la sesión se pierde tras reiniciar o solo funciona una vez, revisa estas variables y reinicia el servidor de dev.
Roles
user
: por defecto.admin_ro
: solo lectura; puede listar usuarios, pedidos y ver créditos de un usuario.admin_rw
: lectura + operaciones; además puede otorgar créditos (trans_type = system_add
).
La migración 0001_add_user_role.sql
añade users.role
con valor por defecto user
.
Autorización
src/lib/authz.ts
obtiene el rol desde la sesión/BD:requireAdminRead()
→ permiteadmin_ro
/admin_rw
.requireAdminWrite()
→ permiteadmin_rw
.
Endpoints de Admin
GET /api/admin/users
→ lista de usuarios (paginaciónpage
,limit
).GET /api/admin/orders
→ pedidos pagados (paginación).GET /api/admin/users/:uuid/credits
→ resumen de créditos.POST /api/admin/credits/grant
→ otorga créditos comosystem_add
.
Pasos de configuración
- Migrar BD:
pnpm drizzle-kit migrate --config src/db/config.ts
- Verificar endpoints (con una cuenta admin).
Cambiar roles
Usa la base de datos como fuente de verdad:
- SQL:
update users set role = 'admin_rw' where uuid = '<uuid>';
- Helper de código:
updateUserRole(uuid, 'admin_ro' | 'admin_rw' | 'user')
ensrc/models/user.ts
.
Notas
- Protege cuentas admin con MFA/SSO y sesiones más cortas.
- Asegura páginas de admin en componentes de servidor y redirige si no hay permisos.
- Los roles no se configuran por .env; cámbialos en la BD.
Inicio de sesión social (Google)
- El proveedor está configurado en
src/lib/auth.ts
dentro desocialProviders.google
y tomaGOOGLE_CLIENT_ID
/GOOGLE_CLIENT_SECRET
de.env
. - Asegúrate de definir:
GOOGLE_CLIENT_ID
,GOOGLE_CLIENT_SECRET
, y tambiénBETTER_AUTH_URL
yNEXT_PUBLIC_AUTH_BASE_URL
(por ejemplohttp://localhost:3000
en desarrollo). - En Google Cloud Console → Credentials, añade la URI de redirección autorizada:
http://localhost:3000/api/auth/callback/google
(dev)https://tu-dominio.com/api/auth/callback/google
(prod)
- La pantalla
/[locale]/login
muestra un botón “Continuar con Google” que inicia el flujo OAuth.
Inicio rápido
Ejecuta la plantilla Sushi SaaS en local con pnpm, recorre rutas i18n, health checks y blogs MDX, y aprende dónde configurar autenticación, pagos y documentación.
Configuración de Stripe
Usa Stripe Checkout para pagos y finaliza vía webhooks para otorgar créditos. Configura variables de entorno, crea sesiones, maneja callbacks y procesa eventos firmados.