web-dev-qa-db-fra.com

Comment authentifier WP REST avec authentification JWT à l'aide de l'API Fetch)

Mon objectif est d'envoyer des commentaires d'utilisateurs avec une demande POST d'une fonction Lambda côté serveur à mon WordPress API. J'utilise Gatsby et Netlify .

Lorsque quelqu'un laisse un commentaire dans le formulaire de commentaire de mon frontal Gatsby, Netlify reçoit un événement de soumission de formulaire et un fonction Netlify Lambda est appelé. C'est dans cette fonction que je vais préparer et envoyer le commentaire à mon site WordPress via WP-REST API .

Le problème est que ma fonction semble échouer silencieusement. Cela peut être dû en partie à la façon dont Netlify met à disposition ses journaux de fonctions. Mon intuition était que une certaine forme d'authentification était nécessaire pour POST un commentaire à WP REST API, donc j'ai continué et installé le JWT Authentication Plugin (principalement parce que je pense qu'il est plus sûr que Basic Auth, bien que je ne sois pas sûr).

J'ai parcouru la documentation du plugin JWT et apporté les modifications nécessaires à mon fichier .htaccess Et à mon fichier wp-config.php, Notamment l'activation du support CORS et la définition d'une nouvelle clé secrète:

define('JWT_AUTH_SECRET_KEY', 'your-top-secret-key');

Dans ma fonction Lambda, je fais une demande de publication au point de terminaison JWT final:

fetch('https://example.com/wp-json/jwt-auth/v1/token', {
     // credentials: 'include',
     headers: new Headers({
        'Authenticate': 'Basic {what do I put here?}' // Do I need "Basic"?
     })
  })
  .then(response => {
     console.log("Did we get a response? ", response)
     return response.json()
  })
  .then(myJson => {
     console.log(JSON.stringify(myJson))
  })
  .catch(error => {
     console.log("error: ", error);
     throw new Error('Something bad happened.', error)
  })

Ma confusion vient de comment configurer correctement un appel d'authentification, si Je dois m'authentifier, et si j'envoie ou non mon WordPress username:password Ou le jeton Web JSON que j'ai défini dans mon wp-config.php.

Et quel devrait être le format du nom d'utilisateur/mot de passe? Devrait-il être encodé en URL, c'est-à-dire: username=admin&password=Str0ngPass Ou simplement `nom d'utilisateur: mot de passe '.

Cette question semble offrir une approche de travail mais je n'utilise pas Postman et ne peux même pas obtenir de jeton de mon appel Fetch. Quelques réponses supplémentaires que j'ai trouvées sont plus théoriques et n'offrent pas grand-chose en termes d'exemples de code:

J'ai également découvert JWT Web Tokens for Node . Peut-être que je devrais l'implémenter de cette façon?

J'ai trouvé la documentation relative à l'utilisation de fetch pour s'authentifier un peu inégale. Toute aide serait grandement appréciée et je suis heureux de fournir plus de code/info dont vous avez besoin.

2
David Gaskin
'Authenticate': 'Basic {what do I put here?}' // Do I need "Basic"?

Non, ce n'est pas Basic. C'est Bearer. Et l'en-tête est Authorization.

Donc, tout d'abord, obtenez un jeton de /wp-json/jwt-auth/v1/token:

fetch( 'http://example.com/wp-json/jwt-auth/v1/token', {
    method: 'POST',
    body: JSON.stringify( {
        // Username of a user on the WordPress website in which the REST API request
        // is being made to.
        username: 'user',
        // And the above user's password.
        password: 'pass'
    } ),
    headers: {
        'Content-Type': 'application/json'
    }
} )
.then( res => res.json() )
.then( res => console.log( res.token ) );

À ce stade: .then( res => console.log( res.token ) ), vous pouvez mettre en cache le jeton, par exemple dans les cookies du navigateur (document.cookie). Je veux dire, s'il n'y a pas eu d'erreurs (renvoyées par le point de terminaison API REST), alors le jeton est stocké dans res.token.

Une fois que vous avez obtenu un jeton valide, vous pouvez ensuite l'utiliser pour effectuer une demande auprès d'un point de terminaison d'API REST tel que " Créez un commentaire" = - définissez l'en-tête Authorization et définissez sa valeur sur: Bearer <token>, Où dans l'exemple ci-dessus, <token> Est la valeur de res.token.

fetch( 'http://example.com/wp-json/wp/v2/comments', {
    method: 'POST',
    body: JSON.stringify( {
        author_email: '[email protected]',
        author_name: 'Test via REST API',
        content: 'Test comment',
        post: 123
    } ),
    headers: {
        'Content-Type': 'application/json',
        Authorization: 'Bearer <token>'
    }
} )
.then( res => res.json() )
.then( res => console.log( res ) );

Assurez-vous que l'en-tête Authorization est activé

Parce que cet en-tête est requis par le plugin.

Et dans mon cas, l'en-tête Authorization (qui dans PHP est accessible via $_SERVER['HTTP_AUTHORIZATION']) Était manquant/désactivé, j'ai donc dû l'ajouter au fichier de configuration d'Apache (httpd.conf): ( nécessite le redémarrage du serveur Apache)

SetEnvIf Authorization "(.*)" HTTP_AUTHORIZATION=$1

J'ai essayé d'ajouter ceci au fichier (racine) .htaccess, Mais cela n'a pas fonctionné pour moi:

RewriteEngine on
RewriteCond %{HTTP:Authorization} ^(.*)
RewriteRule ^(.*) - [E=HTTP_AUTHORIZATION:%1]

J'espère que cela vous aide, vous et/ou quelqu'un d'autre, à avoir des problèmes avec l'en-tête Authorization. :)

Ressources

3
Sally CJ