2019-ebook-3d-onblue4
Everything you need to know about building mobile apps

Learn what a mobile app can do for your business, how to build a great mobile app, and much more. Enter your email below for our free ebook.

Custom WP-API Authentication

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.

16 Comments

  1. Jeffikus on March 5, 2015 at 3:04 pm

    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.

    • Scott Bolinger on March 5, 2015 at 3:16 pm

      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 😉

      • Jeffikus on March 5, 2015 at 3:36 pm

        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 🙂



      • Scott Bolinger on March 5, 2015 at 3:39 pm

        Awesome, so you’ll do all the legwork for me it sounds like! I’ll be eagerly awaiting your “easy oauth” plugin 😉



      • Elliot Taylor on October 23, 2015 at 12:41 pm

        Any news on this easy oAuth plugin? Or perhaps a resource to learn how to use it? Cheers



    • jtsternberg on March 5, 2015 at 9:03 pm

      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

  2. gregoire on April 8, 2015 at 9:32 am

    Could you explain me where does $check_user_id come ?

    Thks

    • Scott Bolinger on April 8, 2015 at 11:43 am

      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.

  3. Maarten on May 25, 2015 at 8:02 am

    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.”}]

  4. Dave on July 6, 2015 at 5:31 pm

    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’);

  5. Andreas Ek on September 26, 2015 at 2:39 am

    The filter “json_authentication_errors” is changed to “rest_authentication_errors”.

  6. Elliot Taylor on October 23, 2015 at 12:50 pm

    An FYI: Good article here: http://wlcdesigns.com/2015/08/swift-login-to-wordpress-from-your-ios-app/

    Hopefully an oAuth tutorial to follow.

  7. Miguel on November 9, 2015 at 11:45 am

    WP REST API – Authenticate using OAuth2

    https://www.youtube.com/watch?v=pRFCmjiRNco

  8. Roy on July 19, 2016 at 8:16 am

    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

  9. Gnana on December 3, 2016 at 6:12 am

    How to set authentication for get post request itself.

Leave a Comment





Scott Bolinger