Create users in WordPress using the REST API

For a current project, we use WordPress as the backend for a native mobile app. The app is developed by another company. I’m responsible for the WordPress part. The content for the app is being created using multiple custom post types and custom taxonomies, as well as some special blocks for a better editing experience. The app can be used without any registration. But some features need a registration, such as synchronizing results on multiple devices or comparing results with other users.

Preparing the server to accept requests

In order to make requests to the server, some response headers have to be set, especially for the iOS version. I first tried to set them using the server configuration, just to realize, that WordPress sets some response headers as well, which resulted in some duplicate headers with the same key, but different values. After some debugging I’ve found some hooks I could use:

function app_rest_headers_allowed_cors_headers( $allow_headers ) {
	return array(
		'Origin',
		'Content-Type',
		'X-Auth-Token',
		'Accept',
		'Authorization',
		'X-Request-With',
		'Access-Control-Request-Method',
		'Access-Control-Request-Headers',
	);
}
add_filter( 'rest_allowed_cors_headers', 'app_rest_headers_allowed_cors_headers' );

For another hook there was no filter, so I had to explicitly call the PHP header() function for this one:

function app_rest_headers_pre_serve_request( $value ) {
	header( 'Access-Control-Allow-Origin: *', true );
	return $value;
}
add_filter( 'rest_pre_serve_request', 'app_rest_headers_pre_serve_request', 11 );

After this small preparation, we can try to create a user with the users endpoint, but this is not going to work. Why not? Well, simply because you cannot create a user for a WordPress site using the REST API without authorization. If that would be possible, that wouldn’t really be good, because otherwise anyone could register a user on an WordPress site.

Authenticate a user with the REST API

So how to we authenticate against the REST API? There are different ways. A very new one is just around the corner and it’s going to be the first one to be integrated into Core: Application Passwords.

There is currently a proposol to integrate the feature project into the upcoming WordPress 5.6. If you want to use it already, you can install the plugin Application Passwords.

Create an app user for the user management

By default, only admin users can manager users. But you probably don’t want to allow an app to have every capability an admin has on a WordPress site. Therefore it’s better to create a special user that only has those capabilitites managing users. You can do that by using a plugin like Members, create a role and a user with PHP code or you use the WP-CLI:

wp role create app App --clone=subscriber
wp cap add app create_users
wp user create app-rest-user app-rest-user@example.com --role=app

The user needs to have at least the create_users capability to create users and you should also add the read capability, so you can login with the new user and set the application password (this is why we clone the “subscriber” role in the example above). Alternatively you can set the application password for a user with an admin user.

Get the application password for the new user

After you have created the user, login with that user and navigate to the profile settings (or edit it’s profile with an admin user). Here you find a new profile field to create application passwords. Choose a name and hit “Add new”:

This will open a modal with the generated password. You have to copy that password from the modal, as you cannot get it’s plain text after closing the modal.

Now we have everything we need for your API call to create users.

Create your first user

Depending on which system you use to make calls against the WordPress REST API, you workflow looks different. I’ll just use a plain curl call from the terminal to demonstrate the request:

curl --user "app-rest-user:younfj4FX6nnDGuv9EwRkDrK" \
     -X POST \
     -H "Content-Type: application/json" \
     -d '{"username":"jane","password":"secret","email":"jane@example.com"}' \
     http://example.com/wp-json/wp/v2/users

If you have set up everything correct, you should get a JSON response with the data of the new user.

Conclusion

Managing users is possible with some setup work and (currently) some external authentication plugins, but with the new applications password feature it will become a lot easier. In a similar way you can make any other call to the REST API that needs an authorized user. For better security, it’s best to create a specific user for such calls (unless you want to create content assigned to a specific user).

Posted by

Bernhard is a full time web developer who likes to write WordPress plugins in his free time and is an active member of the WP Meetups in Berlin and Potsdam.

Leave a Reply

Your email address will not be published. Required fields are marked *