4

I'm playing around with the WP REST API and have setup a route that is used to create a new user when a form is submitted from the homepage. Here is how I setup the endpoint:

add_action('init', 'test_init');

function test_init() {
   // register the route
   add_action('rest_api_init', function () {
     register_rest_route( 'test/api/v1', '/user/add', array(
         'methods' => 'POST',
         'callback' => 'test_add_user',
     ));
   });
}

function test_add_user() {
   // make sure all data is available
   if (!isset($_POST['firstname'], 
              $_POST['surname'],
              $_POST['email'],
              $_POST['password'])) {
      exit;
   }

   // check so the user not already exists
   if (username_exists($_POST['firstname'])) {
      exit;
   }

   // create a new user
   $user = array(
      'user_pass' =>  $_POST['password'],
      'user_login' => $_POST['firstname'],
      'user_email' => $_POST['email'],
      'first_name' => $_POST['firstname'],
      'last_name' => $_POST['surname'],
      'role' => 'author'
    );

    $user_id = wp_insert_user($user);

    // return the id of the created user
    echo json_encode(array('id' => $user_id));
    exit;
}

What I'm wondering is how to best prevent external access to this route? I only want data from the actual form on the homepage to be able to post data to this endpoint.

I tried to check the origin in the callback, but I'm unsure if this is the correct way to do this:

function test_add_user() {
   // only allow request from the same origin
   if (get_http_origin() != home_url()) {
     exit;
   }

   ...
}

I though about perhaps using nonces or something along that line?

Perhaps I also should mention that the user submitting the form is not logged in so I cannot use a cookie based authentication or similar.

1

I would suggest to not use WP REST API for this purpose, since it's being used on homepage and not any remote app/service.
The REST API is supposed to grant access to any already publicly available data to a remote developer.
Since you're not providing any public data but registering users from homepage, Ajax might be a good alternative.
From official WordPress REST API Handbook

WordPress REST API provides API endpoints for WordPress data types that allow developers to interact with sites remotely by sending and receiving JSON (JavaScript Object Notation) objects. 

However this is not its only use case.

I would suggest to use Ajax for this purpose.

  • Include the nonce with Ajax request.

  • Hook the Ajax request handler with wp_ajax_nopriv action.

This makes sure the user is not logged in and the nonce makes sure that the form was generated by WordPress.
There are plugins already available for Ajax user registration, premium and free, WordPress plugins repository will be a good start.
I hope this alternative approach helps.

  • Yes I was also thinking along these lines. The reason that I wanted to use the actual REST API was just to learn more about it and I'm aware that it should not really be used for this purpose, but I was still wondering if there was a way to handle my specific situation. I also read that the REST API is faster then using ajax-admin.php. It also seems much cleaner to register a group of endpoints than hooking into every ajax callback. – Cyclonecode Feb 11 '17 at 9:42
  • 1
    @Cyclonecode I agree, but my answer was specific to this situation, consider a scenario : Users visits your site -> Registers -> and gets logged in -> all happening via Ajax providing a much better user experience. Whereas REST API doesn't really make any difference from the users point of view. So why use it for registration? BUT if you happen to make an app/service will will allow users to get registered to your WordPress blog, REST API is the way you should go. REST API is not an alternative to Ajax, however in this case Ajax will be more beneficial. – devkabiir Feb 11 '17 at 10:05
  • There has to be a way - they are redoing the entire wp-admin using REST API – themerlinproject Mar 8 '17 at 16:48
  • 1
    In my opinion, WordPress Rest API is still not ready for this kind of use case. Just last month (Sucuri)[blog.sucuri.net/2017/02/… published this blog post, using Rest API for this kind of thing only opens a new way for attackers to compromise your site. – devkabiir Mar 8 '17 at 16:54

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.