Cómo hacer peticiones autenticadas con JWT a la API de WordPress
Esto no es realmente una pregunta sino una guía sobre cómo realizar peticiones autenticadas a la API de WordPress usando JWT. Escribo esto como recordatorio para mí mismo y para aquellos que puedan necesitar ayuda con el mismo tema.

¿Por qué autenticación JWT?
Estoy construyendo un sitio que usa WordPress como back-end y una aplicación React+Redux como front-end, por lo que obtengo todo el contenido en el front-end realizando solicitudes a la API de WordPress. Algunas solicitudes (principalmente POST) deben estar autenticadas, y es aquí donde encontré JWT.
Lo que necesitamos
Para usar autenticación JWT con WordPress, primero necesitamos instalar el plugin JWT Authentication for WP REST API. Como se explica en las instrucciones del plugin, también necesitamos modificar algunos archivos centrales de WordPress. En particular:
En el archivo .htaccess incluido en la carpeta raíz de la instalación de WordPress, debemos agregar las siguientes líneas:
RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]
En el archivo wp-config.php, también en la carpeta raíz de WordPress, debemos agregar estas líneas:
define('JWT_AUTH_SECRET_KEY', 'tu-clave-secreta'); // Reemplaza 'tu-clave-secreta' con una clave secreta real.
define('JWT_AUTH_CORS_ENABLE', true);
Verificando si JWT está disponible
Para verificar que ahora podemos usar JWT, abre Postman y realiza una solicitud al 'índice' predeterminado de la API de WordPress:
http://ejemplo.com/wp-json/
Algunos nuevos endpoints, como /jwt-auth/v1
y /jwt-auth/v1/token
, deberían haberse agregado a la API. Si los encuentras en la respuesta a la solicitud anterior, significa que JWT ahora está disponible.
Obteniendo el token JWT
Permanezcamos en Postman por ahora y solicitemos un token a la API de WordPress:
http://ejemplo.com/wp-json/jwt-auth/v1/token
La respuesta contendrá el token JWT, que es una clave encriptada similar a esto:
eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJodHRwOlwvXC9sb2NhbGhvc3Q6ODg4OFwvZm90b3Jvb20tbmV4dCIsImlhdCI6MTUyMjU5NzQ1MiwibmJmIjoxNTIyNTk3NDUyLCJleHAiOjE1MjMyMDIyNTIsImRhdGEiOnsidXNlciI6eyJpZCI6IjEifX19.hxaaT9iowAX1Xf8RUM42OwbP7QgRNxux8eTtKhWvEUM
Realizando una solicitud autenticada
Intentemos cambiar el título de una publicación con ID 300 como ejemplo de una solicitud autenticada con JWT.
En Postman, elige POST como método y escribe el siguiente endpoint:
http://ejemplo.com/wp-json/wp/v2/posts/300
Selecciona "No Auth" en la pestaña Authorization y agrega lo siguiente en la pestaña Headers:
'Content-type': 'application/json',
'Authorization': 'Bearer tokenJWT' // Reemplaza tokenJWT con el token real (la clave encriptada anterior)
Finalmente, en la pestaña Body, selecciona las opciones raw y JSON (application/json), luego en el editor escribe lo siguiente:
{ "title": "¡SÍ! Las solicitudes autenticadas con JWT funcionan" }
Ahora puedes presionar SEND. Revisa en la pestaña de respuesta todos los datos sobre la publicación que solicitamos: el valor de la clave title ahora debería ser ¡SÍ! Las solicitudes autenticadas con JWT funcionan

¿Cómo distinguirías entre llamadas que deben estar autenticadas y aquellas que no necesitan autenticación en el back-end?

También estoy construyendo una aplicación React que obtiene los datos de las publicaciones de la base de datos de WordPress utilizando la API REST de WordPress, sin embargo, no quiero que los endpoints de la API REST estén disponibles públicamente. ¿Hay alguna manera de restringir el acceso a la API REST excepto para mi aplicación React?

@chris Si deseas que tus endpoints estén ocultos de solicitudes no autorizadas, agrégalos bajo el espacio de nombres jwt_auth, es decir, de esta manera: register_rest_route( 'jwt-auth/v1', 'your_custom_endpoint ...
. Cualquier cosa bajo /jwt-auth/ requerirá autorización

@uruk una vez que tienes el token JWT, creo que siempre puedes enviarlo, por lo que no necesitas distinguir cuál se necesita y cuál no.

Como veo, este plugin no se ha actualizado durante tanto tiempo, ¿sigue siendo seguro de usar?

@Lai32290 Este plugin parece estar actualizado y parece estar basado en el plugin mencionado en esta pregunta: https://wordpress.org/plugins/jwt-auth/

@uruk así es como diferencié entre llamadas que deben autenticarse y aquellas que no, sin plugin: Cómo forzar autenticación en REST API para páginas protegidas por contraseña usando tabla personalizada y fetch() sin Plugin

Complementando la respuesta de @grazianodev, así es como puedes obtener tu token de autorización usando cURL:
/**
* Genera un token JWT para futuras llamadas a la API de WordPress
*/
private function getToken() {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,'https://site.localhost/wp-json/jwt-auth/v1/token');
curl_setopt($ch, CURLOPT_POST, 1);
# Credenciales de administrador aquí
curl_setopt($ch, CURLOPT_POSTFIELDS, "username=admin&password=Str0ngPass");
// recibir respuesta del servidor ...
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec ($ch);
if ($server_output === false) {
die('Error al obtener el token JWT en WordPress para integración API.');
}
$server_output = json_decode($server_output);
if ($server_output === null && json_last_error() !== JSON_ERROR_NONE) {
die('Respuesta inválida al obtener el token JWT en WordPress para integración API.');
}
if (!empty($server_output->token)) {
$this->token = $server_output->token; # El token está aquí
curl_close ($ch);
return true;
} else {
die('Respuesta inválida al obtener el token JWT en WordPress para integración API.');
}
return false;
}
Después de esto, envía tus solicitudes con el encabezado: "Authorization: Bearer $token"
Donde $token es el token devuelto por la función getToken() anterior.
Personalmente uso el plugin "Disable REST API and Require JWT / OAuth Authentication" para restringir el acceso a la API solo con el token mencionado.
