Custom WP-API Authentication
The WP-API is a JSON REST API that is slated to go into WordPress core. The API allows applications like mobile apps to interact with WordPress.
It’s been written about extensively, and it’s documented well. If you’ve worked with the API before, you may have come across the issue of authentication.
The API can allow you to create a post, get information about users, and lots more. For that reason, it has to make sure you are allowed to do that. The process for figuring out who can do these things is called authentication, and it can be a pain.
The documentation on authentication is sparse, with options for cookie, oauth, or basic authentication. In this post I will show you how to create your own custom authentication.
Note: the WP-API is going through some major changes before it goes into WordPress core, so this process may change.
Let’s say I made a mobile app where a user can take a photo and upload it to their own WordPress site. The mobile app user would need to login first, then we need to tell the API that they are authenticated. How do we do that?
I’m going to show you how to make a custom authentication filter for this use-case. Disclaimer: I’m not a security expert, so it’s up to you to make sure whatever authentication you use is secure.
Using a custom filter
There is a filter called json_authentication_errors
that allows you to return a boolean value to authenticate an API request.
This is a custom plugin you have to create and activate on your WordPress site, assuming you also have the WP-API plugin active. The code looks like this:
function checkApiAuth( $result ){ // Check if user is allowed to do stuff here if($user_checks_out) { $result = true; } else { $result = false; } return $result; } add_filter('json_authentication_errors', 'checkApiAuth');
With this plugin active on your site, anytime it returns true the user will be able to post to your site, get user information, post meta, and more. If it returns false, they will only be able to do the actions that don’t require authentication, such as getting a list of posts.
One example of how this could work in our app is to verify a token for a user. Let’s say when a user logs into your app, a token is set in the app and in the user meta. In our API filter, we can check if the token in the app matches the token in the user meta.
That would look like this:
function checkApiAuth( $result ){ // if user and token from app match user meta in wp, continue $app_token = $_GET['app_token']; $user_id = $check_user_id; $wp_token = get_user_meta( $user_id, 'app_token', true); if( empty( $app_token ) ) $result = false; if( $wp_token === $app_token ) $result = true; return $result; } add_filter('json_authentication_errors', 'checkApiAuth');
In this case, we would send the app_token along with each API request, which looks like this:
https://mysite.com/wp-json/posts?app_token=13353409ufdhls
Our custom filter checks if the app_token matches the token stored in the user meta. You’d also have to be sending along the user id, so we know which user meta to check. I did not include that in the code above, because it wouldn’t be secure to send both the user id and the token in every request.
Security
This is just an example, and it’s probably not the most secure way to interact with the API. You need to make sure your token cannot be intercepted and used maliciously.
The authentication methods recommended in the WP-API docs such as oAuth are probably a better way to go for a production app. However, for a simple app a custom authentication method may work just fine, as long as you harden the security as much as possible.
Do you know of any actual examples where the WP API OAuth has been implemented? I’ve spent hours trying to figure this out and the docs are shockingly bad.
Unfortunately I don’t. I’ve been holding off on that since things may change once it gets into core, and honestly because OAuth scares me 😉
Lol fair enough, I’ve been doing a LOT of research into this and it’s super frustrating. My end goal is help make the OAuth stuff easier for the WP API, but it’s not an easy task 🙁 I’ve even talked to some OAuth service providers about possibly contributing back to the project, but nothing yet! 🙁
Hit me up on Skype if you are keen to chat further 🙂
Awesome, so you’ll do all the legwork for me it sounds like! I’ll be eagerly awaiting your “easy oauth” plugin 😉
Any news on this easy oAuth plugin? Or perhaps a resource to learn how to use it? Cheers
If you’re looking to OAuth in via another WP installation (rare, but possible), we’ve created this helper library: https://github.com/WebDevStudios/WDS-WP-JSON-API-Connect
Could you explain me where does $check_user_id come ?
Thks
Hi, that was intentionally left out of the article, because you need to find a secure way to get the user_id in WordPress based on information you sent from the app. We will write a follow up article with more information soon.
Hello,
I didn’t totally get the working of this plugin but need it for a project. How i use the first solution?
myurl.com/wp-json/users?json_authentication_errors=true.
Because after activating your solution as a plugin the url /wp-json/users stil returns:
[{“code”:”json_user_cannot_list”,”message”:”Sorry, you are not allowed to list users.”}]
Hi Maarten, some things have changed with authentication, I need to revise this article. For now, I would recommend using the Basic Auth plugin by Ryan McCue. You can customize some of the checks, the code is here: https://github.com/WP-API/Basic-Auth/blob/master/basic-auth.php
Hey everyone, as mentioned, this probably isn’t the most secure solution, however, here is some code using this method that works. Good for development 🙂
function checkApiAuth( $result ){
// if user and token from app match user meta in wp, continue
$user = get_current_user_id();
$app_token = get_query_var(‘app_token’);
$wp_token = get_user_meta($user, ‘app_token’, true);
if( is_user_logged_in() && $wp_token === $app_token ) {
$result = true;
} else {
$result = false;
}
return $result;
}
add_filter(‘json_authentication_errors’, ‘checkApiAuth’);
The filter “json_authentication_errors” is changed to “rest_authentication_errors”.
An FYI: Good article here: http://wlcdesigns.com/2015/08/swift-login-to-wordpress-from-your-ios-app/
Hopefully an oAuth tutorial to follow.
WP REST API – Authenticate using OAuth2
https://www.youtube.com/watch?v=pRFCmjiRNco
Hi Scott
With excellent help coming from your blog, and I am creating a small app using C# using WP-API.
I am facing a small issue in authentication with WP-API and WP oAuth plugin.
The issue is bit strange. I am able to do posts to wordpress (hosted on a free server 16 mb.com). But however when I try running the same code for a blog hosted in my own server, I keep encountering the 403 forbidden issue. I checked lot of forums, and tried many alternatives but still could’nt figure it out. Would be great if you could see where I am going wrong. I posted the question at Stackoverflow here: http://stackoverflow.com/questions/38458678/post-on-wordpress-using-wp-rest-api-c-sharp
How to set authentication for get post request itself.