How to add authorization header in Wordpress to external api request

Hi, maybe someone can help me with the following:

I am running a wordpress site with the auth0 plugin. This is working.
I would like to create authenticated request to a custom nodejs API server I created. For this I created a custom Wordpress plugin with a [shortcode]. When this shortcode is called it sends a request to the api using wp_remote_get(url,args)
This NodeJS API validates the request using node-auth0

How do I add the proper authorization token to the request? Right now the Authorization header is not added.

Regards, Arn

Hi @arn, happy to help!

You’re trying to send the ID token for a particular user? We don’t currently store the ID token in the usermeta because it’s just a lot of extra data that we don’t use elsewhere in the plugin. You’ll need to use one of the hooks in the plugin to store the token on login. This one should work:

Store the $id_token parameter in a usermeta field, then use that in your remote request like:

$remote_url = 'https://yournodeapi.com/api/endpoint';
$id_token = get_user_meta( $user_id, 'auth0_id_token', true); 
$args = array(
    'headers'     => array(
        'Authorization' => 'Bearer ' . $id_token,
    ),
); 
$result = wp_remote_get( $remote_url, $args )
2 Likes

Wow, thank you! I got it working by using the auth0_user_login hook, store the token in the usermeta and add it to the headers as you described.
I had to enable the client-credentials grant in the Auth0 Wordpress application (regular web application).

I am still confused wether I have to use the id_token or access_token to make authenticated requests. That’s something to try for tomorrow. Probably the access_token, since I need the user_id of my api-database which is stored in the app_metadata to do the queries for the current user.

Also, I guess the token needs to be refreshed at some point. Probably the token lifetime is shorter than the login-session.

Yes, it is working!
In custom wordpress plugin:

function dhm_hook_auth0_user_login( $user_id, $userinfo, $is_new, $id_token, $access_token, $refresh_token ) {
  update_user_meta( $user_id, 'auth0_id_token', $id_token);
}
add_action( 'auth0_user_login', 'dhm_hook_auth0_user_login', 10, 6 );

function dhm_balance_shortcode() {
  $user_id = get_current_user_id();
  $id_token = get_user_meta( $user_id, 'auth0_id_token', true);
  $remote_url = 'https://***.localtunnel.me';
  $args = array(
    'headers' => array(
      'Authorization' => 'Bearer ' . $id_token,
    ),
  );
  $response = wp_remote_get( $remote_url, $args );
  $response_code = wp_remote_retrieve_response_code( $response );
  $response_body = wp_remote_retrieve_body( $response );

  return $o;
}

function dhm_shortcodes_init() {
  add_shortcode('dhm_status', 'dhm_balance_shortcode');
}

add_action('init', 'dhm_shortcodes_init');

In the nodeJS application I had to remove the audience field in the jwt-check …

1 Like

For future reference about the audience issue:
This seems to solve it:

Copying straight from the example generated by the quickstart, I got the “jwt audience invalid”. I had to change “audience” to “aud” too to get it working.

Looks good, thanks for sharing that!

One thing to consider … you’re relying on an HTTP call during page load, which could slow down or even stop the page from loading if it doesn’t complete correctly. You might want to look into doing that with AJAX. Also, if wp_remote_get can’t complete you’ll want to handle that.

RE: the token to use … the access token is generated for access to the Auth0 API. If you want to figure out the user that’s sending the request, you’ll want to use the ID token, as you have.

Yes, thanks for the update.

I decided to handle the calls to the API completely in javascript. I add the stored id_token using wp_localize_script(). The wordpress module is now very simple:

function dhm_hook_auth0_user_login( $user_id, $userinfo, $is_new, $id_token, $access_token, $refresh_token ) {
  update_user_meta( $user_id, 'auth0_id_token', $id_token );
}
add_action( 'auth0_user_login', 'dhm_hook_auth0_user_login', 10, 6 );

function dhm_scripts() {
  wp_enqueue_script( 'dhm_api', plugin_dir_url( __FILE__ ) . '/js/api.js', array( 'jquery' ), '1.0.11', true );
  $user_id = get_current_user_id();
  $data = array(
    'url' => 'https://**.localtunnel.me', // Todo: configuration options
    'user_id' => $user_id,
    'id_token' => get_user_meta( $user_id, 'auth0_id_token', true )
  );
  wp_localize_script( 'dhm_api', 'php_vars', $data );
}
add_action( 'wp_enqueue_scripts', 'dhm_scripts' );

And the javascript (/js/api.js):

jQuery(document).ready(function( $ ) {
  if (!php_vars) { return; }
  // Todo: check conditions ( user_id, id_token present )
  // fetch current balance
  function fetchCurrentBalance() {
    $.ajax({
      url: php_vars.url,
      type: 'GET',
  	  dataType: 'json',
      headers: {
        'Authorization': 'Bearer ' + php_vars.id_token
      },
      contentType: 'application/json; charset=utf-8',

      success: function(response) {
        console.log(response);
        let html = 'Balance: ' + response;
        $('#dhm-balance').html( html );
      },

      error: function(errorThrown) {
        console.log(errorThrown);
        $('#dhm-balance').html( 'error' );
      }
    });
  }

  // Fetch widget from API if needed (div id="dhm-xxx")
  if ( $('#dhm_balance') ) { fetchCurrentBalance(); }
  
});

In this case the drawback is that there is an API-request for every page-load where this div is rendered. But at this time the API can handle this easily.

3 Likes

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.