¿Te preocupa que tus peticiones a wp-json devuelvan 401 o que los tokens JWT fallen en producción? Esta guía ofrece pasos concretos, configuraciones y comprobaciones para recuperar la autenticación, endurecer el sistema y automatizar la renovación de tokens en proyectos WordPress.
Índice
Anuncio
Puntos clave: Lo que debes saber en 1 minuto
- La mayoría de los fallos 401 provienen de cabeceras faltantes o bloqueadas: servidores (Apache/Nginx) y proxies suelen eliminar Authorization.
- Verificar firma, algoritmo y secret es imprescindible: tokens mal firmados o con algoritmo incorrecto se rechazan inmediatamente.
- CORS y Authorization deben configurarse en servidor y en WordPress para SPAs y apps externas.
- Usar RS256 y JWKS mejora la seguridad frente a secretos compartidos (indicative, situación a 2026).
- Implementar refresh tokens y revocación evita accesos prolongados en caso de compromiso.
Por qué falla la autenticación JWT en wp-json
La autenticación JWT en la Rest API de WordPress puede fallar por múltiples razones; agruparlas ayuda a priorizar la resolución:
Cabeceras Authorization no llegan al entorno PHP
- Muchos hostings y proxies eliminan la cabecera Authorization por defecto. Si PHP no recibe HTTP_AUTHORIZATION, WordPress no puede validar el token.
- En Apache suele necesitarse RewriteRule o SetEnvIf; en Nginx es necesario forward con fastcgi_param.
Token mal formado, expirado o con firma inválida
- Tokens corruptos o manipulados devuelven 401. Revisar estructura (header.payload.signature) y decodificar en base64 para comprobar claims.
- Si el secret cambió (rotación de claves) y no se reemiten tokens, la verificación falla.
Algoritmo inconsistente (HS256 vs RS256)
- Plugins por defecto usan HS256 (clave simétrica). Si la implementación cliente usa RS256 pero el servidor espera HS256, la verificación no coincide.
Conflictos entre plugins o filtros de autenticación
- Otros plugins que interfieren con rest_authentication_errors, application passwords o sesiones pueden producir denegaciones.
Permisos y capacidades del usuario
- Aunque el token sea válido, las capacidades de usuario en WordPress (roles y capacidades) deben permitir el endpoint solicitado.
Nonces y CSRF en peticiones desde el frontend
- Para peticiones que además usan nonces de WP, un nonce inválido o ausente puede producir errores relacionados con permisos.
Diferencias en la URL base y dominios (issuer/aud)
- Tokens emitidos para un dominio distinto al que valida (aud/iss) se consideran inválidos.
Anuncio
Soluciones para error 401 y tokens inválidos
Resolver 401 exige un flujo de diagnóstico y acciones concretas:
Diagnóstico rápido (checklist)
- Comprobar la cabecera Authorization con una herramienta como Postman o curl: curl -H "Authorization: Bearer
" https://midominio.com/wp-json/wp/v2/posts - Decodificar el JWT en jwt.io o usando jwt-decode para revisar exp, iat, aud, iss y sub.
- Revisar logs PHP y plugins (WP_DEBUG_LOG) para mensajes de rest_authentication_errors.
Reparaciones servidor/hosting
- Apache: añadir en .htaccess dentro del vhost:
RewriteEngine On RewriteRule .* - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
- Nginx con PHP-FPM (configuración típica):
location ~ .php$ { fastcgi_pass unix:/run/php/php8.1-fpm.sock; fastcgi_param HTTP_AUTHORIZATION $http_authorization; include fastcgi_params; }
- Proxies/CDN: asegurar que pasan la cabecera Authorization y no la reescriben.
Reparaciones en WordPress y plugins
- Confirmar que el plugin JWT está correctamente configurado: secret en wp-config.php o configuración segura; matches algorithm.
- Si se usa HS256 asegúrese de que la clave sea lo bastante larga y almacenada fuera del repo (WP_CONFIG define).
- Si se usa RS256, subir la clave pública al verificador y no exponer privada en servidor público.
Validar claims y tolerancia de reloj
- Añadir tolerancia de clock skew (ej. 60s) en verificación para evitar rechazos por desfase horario.
- Confirmar exp no excede el tiempo razonable; tokens demasiado cortos provocan renovaciones frecuentes.
Revocar/rotar claves sin bloquear usuarios
- Implementar una tabla de revocación (blacklist) o introducir un claim jti y compararlo con un store de tokens inválidos.
- Para rotación de claves, mantener versión de clave en token (kid) y aceptar validaciones contra claves antiguas durante ventana de transición.

Configurar cabeceras CORS y Authorization en REST
CORS mal configurado es causa habitual de fallos en SPAs y apps móviles.
Principios prácticos
- Permitir orígenes específicos, no usar "*" cuando se transmite Authorization.
- Añadir cabeceras requeridas: Access-Control-Allow-Origin, Access-Control-Allow-Methods, Access-Control-Allow-Headers (+ Authorization, Content-Type).
Ejemplo nginx para CORS (server block)
if ($request_method = 'OPTIONS') { add_header 'Access-Control-Allow-Origin' 'https://app.midominio.com'; add_header 'Access-Control-Allow-Methods' 'GET, POST, OPTIONS, PUT, DELETE'; add_header 'Access-Control-Allow-Headers' 'Authorization, Content-Type, Accept, X-WP-Nonce'; add_header 'Access-Control-Max-Age' 3600; return 204; }
Añadir X-WP-Nonce cuando aplica
- Para peticiones desde el administrador o para endpoints que requieren nonce, enviar X-WP-Nonce junto Authorization.
Ajustes en WordPress (snippet útil)
- Permitir cabeceras CORS y Authorization desde functions.php (con cuidado):
add_action('rest_api_init', function() { header('Access-Control-Allow-Origin: https://app.midominio.com'); header('Access-Control-Allow-Methods: POST, GET, OPTIONS, PUT, DELETE'); header('Access-Control-Allow-Headers: Authorization, Content-Type, X-WP-Nonce'); }, 15);
- algunos hosts bloquean header() en runtime; preferir configuración en servidor.
Plugins recomendados para JWT y seguridad WordPress
A continuación una comparativa práctica de soluciones y casos de uso.
| Plugin | Ventaja | Limitación |
|---|---|---|
| JWT Authentication for WP REST API | Fácil implementación, compatible con muchas bibliotecas cliente. | Usa HS256 por defecto; requiere ajustes manuales para RS256 y rotación de claves. |
| Application Passwords (Core WP) | Integrado en WP, simple para integraciones server-to-server. | No es JWT; no apto para SPAs que necesitan refresh tokens. |
| Wordfence / Sucuri | Defensa perimetral, bloqueo de IPs y alertas de seguridad. | No gestiona JWT nativamente; complementario. |
Recomendación: para proyectos empresariales, preferir una arquitectura con RS256 y JWKS (clave pública distribuida) o usar un Identity Provider (IdP) externo compatible con OpenID Connect si el alcance lo justifica.
Anuncio
Depurar endpoints REST: logs, nonces y permisos
Depuración ordenada acelera resolución.
Habilitar logging seguro
- Activar WP_DEBUG y WP_DEBUG_LOG en entornos de staging. No dejar logs con tokens en producción.
- Filtrar datos sensibles antes de registrar (masking de Authorization header).
Comprobar rest_authentication_errors
- Hookear rest_authentication_errors para captar errores y devolver mensajes controlados:
add_filter('rest_authentication_errors', function($result) { if (!empty($result)) return $result; // comprobar autorización personalizada return $result; });
Revisar nonces vs tokens
- Los nonces de WP aplican a peticiones desde frontends que usan admin-ajax o REST en contexto de usuario. No mezclar lógicas: usar JWT para autenticación, nonces para protección CSRF si corresponde.
Validar permisos por endpoint
- Implementar permission_callback en register_rest_route que valide capacidades concretas y devuelva errores claros:
'permission_callback' => function($request) { return current_user_can('edit_posts'); }
Ejemplos multi-stack para debug
- Usar curl, Postman o una colección Postman exportada para reproducir peticiones.
- En Node.js, usar fetch/axios y capturar headers enviados.
Prevención: expiración de token y renovación automática
Un diseño seguro de tokens evita accesos permanentes y facilita revocación.
Estrategia recomendada (nivel empresarial)
- Usar access tokens de vida corta (ej. 5-15 minutos) y refresh tokens con mayor vida útil almacenados de forma segura en servidor o en cliente móvil con almacenamiento seguro.
- Implementar endpoint /auth/refresh que exija refresh token y emita nuevo JWT.
- Registrar jti y revocación: almacenar identificador de refresh token para poder revocar sesiones.
Implementación simple con WP
- Crear tabla wp_jwt_sessions con user_id, refresh_token_hash, expires_at, revoked boolean.
- Al emitir refresh, validar hash y expiración. Al revocar, marcar revoked=true.
Evitar fallos comunes en SPAs
- No almacenar refresh tokens en localStorage sin protección XSS. Usar HttpOnly cookies para refresh tokens cuando sea posible.
- Para móviles, usar secure storage nativa.
Flujo de autenticación JWT simplificado
Flujo JWT: emisión, uso y renovación
🔐 Paso 1 → Cliente envía credenciales a /auth (POST)
📝 Paso 2 → Servidor valida, emite access token (corto) + refresh token (largo)
🔁 Paso 3 → Cliente usa access token en Authorization: Bearer
⏳ Paso 4 → Si expira, cliente solicita nuevo access con refresh token
✅ Resultado → Sesión continua sin re-login y posibilidad de revocación centralizada
Anuncio
Ventajas, riesgos y errores comunes
Beneficios / cuándo aplicar ✅
- SPAs o apps móviles: Ideal cuando el frontend consume REST API desde dominios separados.
- Integraciones B2B: Tokens permiten auditoría y control por sesión.
- Microservicios: JWT facilita verificación distribuida si se usan firmas públicas (RS256).
Errores que debes evitar / Riesgos ⚠️
- Almacenar tokens en localStorage sin protección XSS: permite robo por XSS.
- Evitar secretos compartidos sin rotación: un leak compromete todos los tokens.
- No implementar revocación: tokens válidos permanecen activos hasta expiren.
Preguntas frecuentes
¿Por qué recibo 401 aunque el token parezca correcto?
Comprobar primero que la cabecera Authorization llega al proceso PHP. Si llega, validar firma y claims (exp, iat, aud); normalmente el fallo está en signature o secret.
¿Cómo paso Authorization en Apache y Nginx?
En Apache usar RewriteRule para exponer HTTP_AUTHORIZATION; en Nginx añadir fastcgi_param HTTP_AUTHORIZATION $http_authorization al bloque PHP-FPM.
¿Es mejor HS256 o RS256 para WordPress?
RS256 (firma asimétrica) es más seguro en arquitecturas distribuidas porque la clave privada no necesita compartirse; HS256 es más sencillo pero obliga a gestionar secrets con mucho cuidado.
¿Cómo implementar refresh tokens en WordPress?
Crear endpoint seguro /auth/refresh, almacenar refresh_token_hash en base de datos y emitir nuevo access token tras validar y comprobar estado de revocación.
¿Puedo usar JWT con Application Passwords de WordPress?
Son mecanismos distintos. Application Passwords son útiles server-to-server; JWT mejor para SPAs y móviles donde se necesita control de sesión y refresh.
¿Qué herramientas ayudan a depurar JWT en WP?
Postman, curl, jwt.io para decodificar, y WP_DEBUG_LOG para capturar errores del plugin o filtros que afecten rest_authentication_errors.
Conclusión
La autenticación JWT en la Rest API de WordPress es potente pero sensible a configuración de cabeceras, algoritmos y gestión de claves. Con una estrategia de claves, revocación y renovación de tokens bien implementada, los fallos 401 se reducen drásticamente y la seguridad mejora.
Siguientes acciones
- Revisar y corregir el paso de la cabecera Authorization en servidor (Apache/Nginx) y proxies.
- Implementar refresh tokens con almacenamiento seguro y revocación (tabla de sesiones) en staging.
- Migrar a RS256/JWKS si la arquitectura implica múltiples servicios o equipos.
- Con 1.000 productos, salva pedidos en Woo: nube o local
- El último backup no siempre es el seguro tras un hackeo
Josu Barrios
Somos especialistas en mantenimiento WordPress para empresas, profesionales y tiendas online. Contamos con experiencia en seguridad web, optimización de rendimiento, actualizaciones, copias de seguridad y resolución de incidencias técnicas, ayudando a que cada sitio funcione de forma rápida, estable y protegida. Nuestro enfoque combina soporte técnico profesional, buenas prácticas de seguridad y seguimiento continuo para ofrecer un servicio fiable, transparente y orientado a resultados reales.