Definition
Cuando haces el check-in en un hotel, la recepcion te da una tarjeta llave. Pero esa pequena tarjeta contiene mas que solo la capacidad de abrir tu puerta - puede codificar a que piso puedes acceder, si tienes privilegios de gimnasio, si estas en el programa VIP, y cuando termina tu estancia. En el mundo digital, los claims funcionan exactamente de la misma manera: son fragmentos de informacion incrustados en tokens de seguridad que le dicen a los sistemas quien eres y que tienes permitido hacer.
Los claims son declaraciones sobre un usuario (o a veces una maquina) que viajan junto con un token de seguridad como un JWT. Piensa en ellos como los “hechos” que tu carnet de identidad digital lleva consigo. Cuando inicias sesion en una aplicacion, el servidor de autenticacion no solo dice “si, esta persona es valida” - empaqueta informacion relevante sobre ti en claims y los envia. La aplicacion que recibe estos claims puede entonces tomar decisiones basadas en esta informacion sin tener que volver a preguntar al servidor de autenticacion cada vez.
Hay tres tipos de claims, y entender la diferencia te ayuda a usarlos correctamente. Los claims registrados son los estandar definidos por especificaciones oficiales - cosas como cuando se emitio el token, cuando expira, y para quien fue emitido. Son como los campos estandar en cualquier documento de identidad gubernamental: nombre, fecha de nacimiento, fecha de expiracion. Los claims publicos son informacion personalizada que usa una convencion de nombres para evitar conflictos - como usar un prefijo de URL para asegurar que tu claim de “roles” no choque con el claim de “roles” de alguien mas. Finalmente, los claims privados son territorio libre - cualquier informacion que el emisor y receptor del token acuerden, como tu departamento, nivel de suscripcion, o color favorito si eso de alguna manera importa a tu aplicacion.
Example
Escenario Real 1: Cambio de Perfiles en Netflix Cuando cambias entre perfiles en Netflix, el token que recibes contiene claims sobre que perfil estas usando, si es un perfil infantil (con restricciones de contenido), tu nivel de suscripcion (que determina la calidad de video), y tus preferencias de visualizacion. La app de Netflix usa estos claims para personalizar toda tu experiencia sin consultar al servidor para cada decision.
Escenario Real 2: Acceso a Google Workspace Cuando estas logueado en Google, tu token contiene claims sobre a que organizacion perteneces, tu direccion de email, si eres administrador, y a que servicios tienes permitido acceder. Cuando intentas abrir Google Analytics, el sistema verifica tus claims para ver si tu organizacion tiene acceso y si tu rol permite ver datos.
Escenario Real 3: Sistemas de Informacion Hospitalaria En un hospital, el token de la Dra. Garcia podria contener claims como “rol: medico”, “departamento: cardiologia”, “nivel_acceso: 3”, y “colegiada_en: [Madrid, Barcelona]”. Cuando intenta acceder a los registros cardiacos de un paciente, el sistema verifica estos claims para confirmar que tiene el rol correcto, afiliacion al departamento y nivel de acceso adecuado - todo sin hacer una consulta a la base de datos.
Escenario Real 4: Niveles de Membresia en E-commerce El estado de membresia Amazon Prime es esencialmente un claim. Tu token podria contener “prime: true”, “prime_desde: 2019-03-15”, “prime_video: true”, “prime_music: false”. Diferentes partes del ecosistema de Amazon verifican estos claims para determinar si ves opciones de envio gratis, puedes acceder a contenido de Prime Video, u obtener ofertas exclusivas para miembros.
Analogia
El Modelo del Carnet de Conducir: Tu carnet de conducir esta lleno de claims. Algunos son registrados y estandarizados - tu nombre, fecha de nacimiento, fecha de expiracion del carnet. Cada pais usa estos mismos campos porque son universalmente entendidos. Algunos son mas como claims publicos - permisos para motocicletas o vehiculos comerciales, codificados de formas que varian ligeramente por pais pero siguen convenciones generales. Y algunos son como claims privados - quiza tu carnet incluye si eres donante de organos o tienes condiciones medicas, que solo importan en ciertos contextos.
El Sistema de Pulseras de Festivales: En un festival de musica, diferentes pulseras otorgan diferentes accesos. La pulsera basica podria solo decir “entrada general”. Una pulsera VIP contiene claims adicionales: “backstage: true”, “zona_vip: true”, “entrada_prioritaria: true”. La pulsera misma lleva toda la informacion - seguridad no necesita buscarte en una base de datos; solo leen los claims de tu pulsera.
La Analogia del Carnet de Biblioteca: Tu carnet de biblioteca codifica claims sobre ti: tu nivel de membresia, tu sucursal principal, si puedes acceder a colecciones especiales, tu limite de prestamos, y el estado de tu cuenta. Diferentes secciones de la biblioteca verifican diferentes claims - la sala de libros raros se preocupa por tu acceso a colecciones especiales, mientras que el mostrador de prestamos se preocupa por tu limite y si tienes libros vencidos.
La Tarjeta de Embarque: Una tarjeta de embarque esta llena de claims. Tu nombre, numero de vuelo, asiento asignado, grupo de embarque, y estatus (economica, business, nivel de viajero frecuente) son todos claims. El agente de la puerta la escanea y sabe inmediatamente todo lo que necesita: Puedes embarcar ahora? Tienes prioridad? Estas en la terminal correcta? Todo esta codificado ahi mismo.
Code Example
// Creando JWT con diferentes tipos de claims
const jwt = require('jsonwebtoken')
function createToken(user) {
const payload = {
// CLAIMS REGISTRADOS ([RFC 7519](https://reference.apios.info/es/terms/rfc-7519/))
iss: 'https://auth.myapp.com', // Emisor
sub: user.id, // Sujeto (identificador de usuario)
aud: 'https://api.myapp.com', // Audiencia
exp: Math.floor(Date.now() / 1000) + 3600, // Expiracion (1 hora)
nbf: Math.floor(Date.now() / 1000), // No antes de
iat: Math.floor(Date.now() / 1000), // Emitido en
jti: generateUniqueId(), // ID JWT (para revocacion)
// CLAIMS PUBLICOS (usar URIs para evitar colisiones)
'https://myapp.com/claims/roles': user.roles,
'https://myapp.com/claims/permissions': user.permissions,
// CLAIMS PRIVADOS (especificos de aplicacion, acordados entre partes)
department: user.department,
email: user.email,
email_verified: user.emailVerified,
plan: user.subscriptionPlan
}
return jwt.sign(payload, process.env.JWT_PRIVATE_KEY, {
algorithm: 'RS256'
})
}
// Validando y extrayendo claims
function validateAndExtractClaims(token) {
try {
const decoded = jwt.verify(token, process.env.JWT_PUBLIC_KEY, {
// Validar claims registrados
issuer: 'https://auth.myapp.com',
audience: 'https://api.myapp.com',
algorithms: ['RS256'],
// Verifica automaticamente exp, nbf, iat
})
// Extraer claims de forma segura con valores por defecto
const claims = {
userId: decoded.sub,
roles: decoded['https://myapp.com/claims/roles'] || [],
permissions: decoded['https://myapp.com/claims/permissions'] || [],
department: decoded.department,
email: decoded.email,
emailVerified: decoded.email_verified || false
}
return claims
} catch (err) {
if (err.name === 'TokenExpiredError') {
throw new Error('Token expirado')
}
throw new Error('Token invalido')
}
}
// Autorizacion usando claims
function hasPermission(token, requiredPermission) {
const claims = validateAndExtractClaims(token)
return claims.permissions.includes(requiredPermission)
}