web-dev-qa-db-fra.com

Vérifiez le nonce dans REST API?

J'aimerais comprendre les meilleures pratiques en matière de validation de nonce dans les API REST.

Je vois beaucoup de gens parler de wp_rest nonce pour REST requêtes. Mais en regardant sur le code principal de WordPress, j'ai constaté que wp_rest est juste un moyen de valider un statut d'utilisateur connecté. S'il n'est pas présent, il exécute simplement la demande en tant qu'invité.

Cela dit, devrais-je soumettre deux noms lors de l'envoi d'une demande POST à une API REST? Un pour l'authentification wp_rest et un autre pour l'action foo_action?

Si oui, comment devrais-je envoyer wp_rest et foo_action nonce en JavaScript et, en PHP, quel est le bon endroit pour valider ces nonces? (Je veux dire validate_callback pour un argument? Permission_callback?)

2
Lucas Bustamante

Je réponds à ma propre question basée sur mes tests. J'ai demandé cela parce que c'est quelque chose que je ne pouvais pas trouver sur Google, alors je voulais poster une solution ici.

La première chose que j'ai faite a été de mettre en file d'attente le JavaScript à l'aide de la fonction wp_localize_script, afin de transmettre les données de PHP à JavaScript:

wp_register_script('foo', 'foo.js');

wp_localize_script('foo', 'fooData', [
    'endpoint' => esc_url_raw(rest_url('/foo/v1')),
    'nonces' => [
        'foo_nonce' => wp_create_nonce('foo_nonce'),
        'wp_rest'   => wp_create_nonce('wp_rest')
    ]
]);

wp_enqueue_script('foo');

Nous passons 2 nonces, foo_nonce et wp_rest. WordPress vérifie wp_rest nonce en interne pour chaque REST demande d'API émise par un utilisateur connecté. (That check is in wp-includes\rest-api.php @ 810 - WordPress 5.0.2). Si ce nonce n'est pas présent, la demande est traitée comme s'il s'agissait d'un utilisateur invité.

Maintenant, dans le JavaScript, nous recevons les données de PHP dans l'objet FooData:

$.ajax({
    url: FooData.endpoint + '/addSomething',
    type: "POST",
    dataType: "json",
    data: {
        // Your other data here
        "foo_nonce": FooData.nonces.foo_nonce
    },
    // This nonce is verified automatically by WordPress for logged-in users
    beforeSend: function (xhr) {
        xhr.setRequestHeader('X-WP-Nonce', FooData.nonces.wp_rest);
    }
});

Lorsque la requête est envoyée au serveur, nous pouvons exécuter wp_verify_nonce sur le validate_callback du champ nonce:

register_rest_route('foo/v1', '/doSomething', [
    'methods' => WP_REST_Server::CREATABLE,
    'callback' => [$this, 'doSomething'],
    'args' => [
        // Your other data here
        'foo_nonce' => [
            'validate_callback' => function($foo_nonce) {
                return wp_verify_nonce($foo_nonce, 'foo_nonce');
            }
        ]
    ]
]);

C'est tout!

2
Lucas Bustamante