How to authenticate for remote access to protected data in LearnDash via the Wordpress REST API?

Viewed 1309

I am developing a mobile app (in Flutter) that needs to access course data of the user from a Wordpress LearnDash LMS environment. The Wordpress site is accessible via the standard REST API through the https://<site>/wp-json/ldlms/v1/ path.

But whenever I try to access e.g. <...>/ldlms/v1/sfwd-courses/<id>/steps, the result is a 401 (Unauthorized) status.

From the Wordpress documentation I learned it uses cookie authentication. But adding the wordpress_logged_in_<hash> cookie to the request header does not seem to make a difference.

Where can I find the missing authentication details required to access this information?

1 Answers

I just built my REST API; so I may be of some help. The example below will:

  1. Register a custom rest api endpoint
  2. Localize server-side variables on first load (endpoint, user object, etc)
  3. Append the NONCE to all rest requests avoiding the hash BS

Rest API Authentication Reference

functions.php

add_action('rest_api_init', 'register_custom_fields');
function register_custom_fields(){
    register_rest_route(
        'app', '/login/',
        [ 'methods' => 'POST', 'callback' => 'asset_login' ]
    );
}
function asset_login(){
    $user = wp_signon($_POST);
    if (is_wp_error($user)){
        return [ 'result' => 'fail', 'error' => $user->get_error_message() ];
    } else {
        return [ 'result' => 'success', 'user' => [ 'ID' => $user->data->ID, 'name' => $user->data->display_name ] ];
    }
}


add_action('init','stage_script');
function stage_script(){

    wp_enqueue_script('asset-library', trailingslashit(get_stylesheet_directory_uri()) . 'js/asset-library.js', ['jquery']);

    $assetUser = null;
    if (is_user_logged_in()){
        $user = wp_get_current_user();

        $assetUser = [
            'ID' => $user->data->ID,
            'name' => $user->data->display_name,
            'nickname' => $user->data->user_nicename,
            'email' => $user->data->user_email,
            'allcaps' => $user->allcaps
        ];
    }

    wp_localize_script( 'your-app', 'App', [
        'user' => $assetUser,
        'api_endpoint' => esc_url_raw( rest_url() ),
        'api_version' => 'wp/v2/',
        'nonce' => wp_create_nonce( 'wp_rest' )
    ]);
}

script.js

    // The Login Controller
    let AppUser = {
        loggedIn: false,
        login: function(data){
            $.ajax( {
                url: App.api_endpoint + 'your-app/login',
                method: 'POST',
                beforeSend: function ( xhr ) {
                    xhr.setRequestHeader( 'X-WP-Nonce', App.nonce );
                },
                data: data,
                success: function(response){
                    /* ... parse response ... */
                },
                error: function(response){
                    /* ... parse response ... */
                }
            });
        }
    };


    // The API Controller
    let QueryController = {
        Objects: [],
        getObjects: async function(){

            let q = {};
            /* ... build query stuff extracted */

            try {
                const response = await $.ajax( {
                    url: App.api_endpoint + App.api_version + 'post_object',
                    method: 'GET',
                    beforeSend: function ( xhr ) {
                        xhr.setRequestHeader( 'X-WP-Nonce', App.nonce );
                    },
                    data: q
                });

                this.Objects = response;
                return response;
            } catch(e) {
                console.log('Error: ', e);
            }
        }
    };
Related