Contents
Introducción
Este artículo explica, paso a paso y con ejemplos prácticos, cómo exponer el nonce de la REST API en el ltheadgt de una página de WordPress utilizando wp_localize_script. Verás por qué y cuándo hacerlo, la forma correcta de implementarlo en un tema o plugin, cómo consumirlo desde JavaScript (fetch/REST), y las consideraciones de seguridad y caché que debes tener en cuenta.
Conceptos clave
- Nonce: token de un solo uso usado por WordPress para proteger acciones contra CSRF. No es una clave criptográfica, tiene caducidad y no sustituye controles de permisos.
- REST nonce: nonce que se genera con wp_create_nonce(wp_rest) y que la REST API reconoce al recibir la cabecera X-WP-Nonce.
- wp_localize_script: función tradicionalmente usada para pasar datos PHP a scripts JS en el front. Crea un objeto JS global con los valores que le pases.
- Head vs Footer: wp_localize_script imprime el objeto JS justo antes del script que hace referencia al handle. Si el script fue encolado para imprimirse en el head (in_footer = false), el objeto aparecerá en el head.
¿Por qué exponer el nonce en el head?
Exponer el nonce en el head mediante un objeto JS global permite que cualquier script cargado en la página (incluido el editor, bloques personalizados o scripts front) pueda realizar peticiones autenticadas a la REST API usando la cabecera X-WP-Nonce. Es una forma cómoda de entregar datos de configuración (URL de la API, nonce, otros parámetros) desde PHP a JavaScript.
No obstante, hay que recordar que los nonces no son secretos absolutos: están disponibles para el usuario que visita la página. Por eso es importante pensar en permisos y caché (más abajo).
Implementación: patrón recomendado
El patrón general es:
- Registrar o encolar tu script con in_footer en false (si quieres que salga en el head).
- Usar wp_localize_script para crear un objeto JS que incluya el nonce generado con wp_create_nonce(wp_rest) y otros datos (rest_url, site_url, etc.).
- Consumir esos valores desde tu JavaScript y enviar el nonce en la cabecera X-WP-Nonce en las peticiones.
Ejemplo práctico en PHP (functions.php o plugin)
se imprime en head ) // Crear datos para JS: nonce de REST, URL base de la API y otros parámetros mi_data = array( rest_nonce => wp_create_nonce( wp_rest ), rest_url => esc_url_raw( rest_url() ), site_url => esc_url_raw( home_url() ), // Añade otros valores que necesites ) // Pasar los datos a JS. El nombre MiPluginData será el objeto global en JS wp_localize_script( mi-plugin-main, MiPluginData, mi_data ) // Encolar el script wp_enqueue_script( mi-plugin-main ) } ?>
Notas:
- Es importante registrar/encolar el script con in_footer = false si quieres que el objeto aparezca en el head.
- wp_localize_script debe llamarse con el handle correcto. Lo normal es registrarlo antes y luego encolar también funciona si ya está encolado mientras el handle exista.
- Usa esc_url_raw para URLs y deja que wp_localize_script se ocupe del escape del valor para JS.
Ejemplo de consumo desde JavaScript (fetch)
// assets/js/main.js // MiPluginData.rest_url y MiPluginData.rest_nonce vienen del objeto global inyectado por wp_localize_script const baseRest = MiPluginData.rest_url.replace( ///, ) // quitar slash final const nonce = MiPluginData.rest_nonce // Ejemplo: POST a /wp/v2/posts (crear borrador) — requiere capacidad adecuada fetch( {baseRest}/wp/v2/posts, { method: POST, headers: { Content-Type: application/json, X-WP-Nonce: nonce }, body: JSON.stringify({ title: Prueba via REST, status: draft }) }) .then( response => response.json() ) .then( data => { console.log( Respuesta de la API:, data ) }) .catch( err => { console.error( Error al llamar a la REST API:, err ) })
Variantes y alternativas
- Elemento meta en head: muchas guías usan un tag meta (ej. ltmeta name=wp-rest-nonce content=…/gt) mediante wp_head es igualmente válido y separado del sistema de encolado de scripts.
- wp_add_inline_script: para añadir un bloque JS inline justo antes o después de un script puede ser más flexible que wp_localize_script para estructuras complejas.
- Para admin o editor: usar la acción admin_enqueue_scripts o hooks específicos del editor si lo necesitas sólo para WP-Admin o Gutenberg.
Consideraciones de seguridad y caché
- Permisos: el nonce no sustituye la necesidad de comprobar capacidades o permisos en tu endpoint REST. Usa permission_callback en tus endpoints personalizados y capacidades apropiadas (current_user_can).
- Caché: nunca incluyas nonces específicos de usuario en HTML que vaya a ser cacheado de forma pública (CDN, cache estático para usuarios anónimos). Si la página se guarda en caché con un nonce de otro usuario, la interacción autenticada puede fallar o, peor, exponer valores. Para páginas cacheadas públicamente, usa mecanismos que no inyecten nonces por usuario o utiliza fragment caching/ESI para zonas autenticadas.
- Caducidad: los nonces expiran (por defecto 24 horas aproximadamente). Ten esto en cuenta para flujos de trabajo largos.
- No exponer para acciones peligrosas: evita poner nonces que permitan operaciones de alto riesgo en páginas públicas sin control de permisos adicional.
Errores comunes y solución
- Handle incorrecto: usar un nombre distinto en wp_localize_script al del script registrado provocará que no se genere el objeto JS.
- Script en footer: si tu script se encola con in_footer = true, el objeto JS también se imprimirá en el footer y no en el head.
- Caché lateral: insertar nonce en HTML cacheado públicamente (ver sección de caché).
- Endpoint rechaza la petición: si la REST API responde 401/403 revisa: nonce correcto, cabecera X-WP-Nonce presente, permiso del usuario y que la ruta REST acepte autenticación por nonce.
Ejemplo para admin/editor (admin_enqueue_scripts)
wp_create_nonce( wp_rest ), rest_url => esc_url_raw( rest_url() ), ) ) } ?>
Resumen práctico
Qué hacer | Registrar/encolar script con in_footer=false, usar wp_localize_script para inyectar wp_create_nonce(wp_rest) y consumirlo en JS con la cabecera X-WP-Nonce. |
Precauciones | Comprobar permisos en el servidor, evitar inyectar nonces en HTML cacheado públicamente y recordar la caducidad del nonce. |
Alternativa | Usar meta tags en head o wp_add_inline_script si prefieres otro método de inyección. |
Referencias útiles
- REST API Authentication — WordPress Developer
- wp_create_nonce — referencia
- wp_localize_script — referencia
|
Acepto donaciones de BAT's mediante el navegador Brave 🙂 |