1

Is it possible to create a sign up form that can work through WP REST API for visitors to be able to create accounts on my site?

I can create such a form and use it to create new users. This works with wp_rest nonce when I am logged in as administrator.

But if there is a visitor which is not logged in, the same form does not work of course. I think this is a question of authentication. Can you suggest a general idea how this can work? How can I allow visitors to be able to sign up with REST API?

5

hopefully you've found the answer already. Here's our solution, for your reference. :D

The following code should add User Registration via REST API to your WordPress Website. It supports Registration of 'subscriber' and 'customer'. Source code also available on Github.

Add it to your function.php

add_action('rest_api_init', 'wp_rest_user_endpoints');
/**
 * Register a new user
 *
 * @param  WP_REST_Request $request Full details about the request.
 * @return array $args.
 **/
function wp_rest_user_endpoints($request) {
  /**
   * Handle Register User request.
   */
  register_rest_route('wp/v2', 'users/register', array(
    'methods' => 'POST',
    'callback' => 'wc_rest_user_endpoint_handler',
  ));
}
function wc_rest_user_endpoint_handler($request = null) {
  $response = array();
  $parameters = $request->get_json_params();
  $username = sanitize_text_field($parameters['username']);
  $email = sanitize_text_field($parameters['email']);
  $password = sanitize_text_field($parameters['password']);
  // $role = sanitize_text_field($parameters['role']);
  $error = new WP_Error();
  if (empty($username)) {
    $error->add(400, __("Username field 'username' is required.", 'wp-rest-user'), array('status' => 400));
    return $error;
  }
  if (empty($email)) {
    $error->add(401, __("Email field 'email' is required.", 'wp-rest-user'), array('status' => 400));
    return $error;
  }
  if (empty($password)) {
    $error->add(404, __("Password field 'password' is required.", 'wp-rest-user'), array('status' => 400));
    return $error;
  }
  // if (empty($role)) {
  //  $role = 'subscriber';
  // } else {
  //     if ($GLOBALS['wp_roles']->is_role($role)) {
  //      // Silence is gold
  //     } else {
  //    $error->add(405, __("Role field 'role' is not a valid. Check your User Roles from Dashboard.", 'wp_rest_user'), array('status' => 400));
  //    return $error;
  //     }
  // }
  $user_id = username_exists($username);
  if (!$user_id && email_exists($email) == false) {
    $user_id = wp_create_user($username, $password, $email);
    if (!is_wp_error($user_id)) {
      // Ger User Meta Data (Sensitive, Password included. DO NOT pass to front end.)
      $user = get_user_by('id', $user_id);
      // $user->set_role($role);
      $user->set_role('subscriber');
      // WooCommerce specific code
      if (class_exists('WooCommerce')) {
        $user->set_role('customer');
      }
      // Ger User Data (Non-Sensitive, Pass to front end.)
      $response['code'] = 200;
      $response['message'] = __("User '" . $username . "' Registration was Successful", "wp-rest-user");
    } else {
      return $user_id;
    }
  } else {
    $error->add(406, __("Email already exists, please try 'Reset Password'", 'wp-rest-user'), array('status' => 400));
    return $error;
  }
  return new WP_REST_Response($response, 123);
}

IMHO, a more better way would to include the additional function as a seperate plugin. So even when your user changed theme, your api calls won't be affected.

Therefore I've developed a plugin for User Registration via REST API in WordPress. Better yet, it supports creating 'customer' for WooCommerce too!

WP REST User, check it out if you want.

1

You could create your own signup routine using wp-includes/rest-api/endpoints/class-wp-rest-users-controller.php (WP v4.7.4) as a reference implementation. You could also modify the WordPress version by doing something like the following:

function nLbwuEa8_modify_create_user_route() {
    $users_controller = new WP_REST_Users_Controller();

    register_rest_route( 'wp/v2', '/users', array(
        array(
            'methods'             => WP_REST_Server::CREATABLE,
            'callback'            => array($users_controller, 'create_item'),
            'permission_callback' => function( $request ) {

                // METHOD 1: Silently force the role to be a subscriber
                // $request->set_param('roles', array('subscriber'));

                // METHOD 2: Be nice and provide an error message
                if ( ! current_user_can( 'create_users' ) && $request['roles'] !== array('subscriber')) {

                    return new WP_Error(
                        'rest_cannot_create_user',
                        __( 'Sorry, you are only allowed to create new users with the subscriber role.' ),
                        array( 'status' => rest_authorization_required_code() )
                    );

                }

                return true;
            },
            'args'                => $users_controller->get_endpoint_args_for_item_schema( WP_REST_Server::CREATABLE ),
        ),
    ) );

} );
add_action( 'rest_api_init', 'nLbwuEa8_modify_create_user_route' );

The important parts being the permission_callback key (where you are essentially disabling authentication). And the args key that could be used to add a captcha so spammers don't overrun the service. Hope this helps.

  • Enabling the ability for arbitrary people to create users is not really safe. They can simply create themselves an Admin level user and take over your site. You should instead use the registration flow, which does not presently have an API call for it. Send them to the wp-login.php?action=register page and let them create an account there. – Otto Sep 9 '17 at 19:53
  • @Otto I was trying to show a proof of concept not the exact implementation. It's been a while since I looked at this but how would it be different from wp-login.php?action=register if the only type of user you could create was a "subscriber" if you are not authenticated? Can I make that clearer in my post? – JSP Sep 10 '17 at 13:03
  • The Rest API route allows you to create users of any role, not just subscribers. Although, it does have a check to prevent role promotion, so that might be acceptable. You'd want to test that you couldn't, for example, just make an Admin level user. – Otto Sep 10 '17 at 14:05
  • @Otto Do you feel like this is a better solution? – JSP Sep 14 '17 at 20:57
  • Nope. It might work, it might not. I have not tested it in any way. – Otto Sep 15 '17 at 12:20
0

I would create a custom route for your site that collects the fields you need and then calls the internal wp_insert_user() function. This way you'd be able to validate the information the user is providing, including restricting which role they're allowed to get. I'd also be tempted to limit the # of users that can be created by the same IP address in a day, or something like that.

0

Now there is a plugin called WP Webhooks that can do this.

According to the plugin page:

It allows you to trigger actions (such as creating a user or a post) in WordPress upon receiving data from other services.

Many form solutions work with Zapier (including Gravity Forms, JotForm, Formidable, and even Google Forms) so one of these could be used to trigger a new user signup using this method.

Wordpress is already has native Zapier support without this plugin, but creating a new user is not a supported action using the native WordPress Zapier app.

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.