How to take a saved API bearer token and make a second request?

By: Steven M | Asked: 07/15/2023
ForumsCategory: How-toHow to take a saved API bearer token and make a second request?
Steven MSteven M asked 1 year ago
HI I am working on API integration. That requires an authentication endpoint https://test-api.com/sign_in/  using the username and password, which returns a token in a format example: “Bearer eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9xxxxxxxxxxxxx” Then it uses the token in the header on the subsequent request to send to https://test-api.com/verify/ different endpoint. Example: {     "countryCode": "AU",     "service": [         "Australia Birth Certificate"     ],     "firstName": "[628]",     "middleName": "[629]", Etc ect… I have created an API action to log in, and this works and it returns the bearer token. I then use this code to store the bearer token in a hidden field, which works as expected. And is below:

add_action( 'frmapi_post_response', 'frm_save_api_response', 10, 3 );
function frm_save_api_response( $response, $entry, $form_action ) {
$body = json_decode($response["body"], true);
$returned_id = $body["sessionToken"]; // 
if ( $returned_id ) {
FrmProEntryMeta::update_single_field( array(
'entry_id' => $entry->id,
'field_id' => 757, // replace with the ID of the field in which you want to save the session token
'value' => $returned_id,
) );
}
}
I now need to initiate a second request with the bearer token to the second endpoint: ttps://test-api.com/verify/ using the token Example:  
{
"headers": {
"Authorization": "[757]" // bearer token
},
"body": {
"countryCode": "AU",
"service": [
"Australia Birth Certificate"
],
"firstName": "[628]",
"middleName": "[629]",
"lastName": "[630]",
"dateOfBirth": "[631]",
"identityVariables": {
"birthRegistrationState": "[632]",
"birthRegistrationNo": "[633]",
"birthCertificateNo": "[634]",
"birthRegistrationDate": "[635]"
},
"consentObtained": {
"Australia Birth Certificate": "[636]"
}
}
}
I tried adding this as a second API action in formidable forms, but it doe not work, and I am guessing because it is firing before the token is stored??

Can anyone help? From my understanding, it's pretty common first to authenticate and then provide a bearer token. 

Are there any solutions to this?? Am I missing something? Can someone please provide a solution? Thanks!!
1 Answers
Victor Font answered 1 year ago
It is a common request, but I never run the first request through the API. Once a form is filled out and a user clicks submit, I use jQuery to block the submit using preventDefault(), run an Ajax call to retrieve the authentication code, then allow the submit to proceed where the second API call executes with the authentication code in place. It's all a matter of timing.
Steven MSteven M replied 1 year ago

So the basic is idea here is:

1. User fills out the form and clicks submit.

2. A jQuery function prevents the default form submission, sends an AJAX authentication request to the server, and saves the authentication token.

3. The form submission proceeds. The Formidable API Action is triggered, which includes the authentication token saved in step 2 in the Authorization header, and sends the second request to the server.

Is this correct?

Cheers

Victor Font replied 1 year ago

Yes. You got it.

Steven MSteven M replied 1 year ago

HI @Victor Font

Thanks for this.

I have been working on this for a day now and can not get it to work, and I can not see where it is failing. Maybe you can see it?? I have tried logging any success or errors an not getting an of that either. I assume I am doing something wrong, and its probably obvious but I can not see it!

If I work this out, I will definitely share the solution because this has got to be frustrating many people.

An guidance is appreciated.

Using "Code snippets" for the functions.

//1st I enqueue the js file using a function here:

function enqueue_custom_scripts() {
wp_enqueue_script('custom-js', content_url() . '/custom_js/custom.js', array('jquery'), '', true );
}
add_action('wp_enqueue_scripts', 'enqueue_custom_scripts');

//2nd:

//custom.js fil in wp-content/custom_js/

jQuery(document).ready(function ($) {
$('#form_id_10').on('submit', function (e) {
console.log('Form submit event triggered');
e.preventDefault()
const formId = $(this).attr('id')

$.ajax({
url: '/wp-admin/admin-ajax.php',
type: 'POST',
data: {
action: 'get_auth_code'
},
success: function (response) {
console.log('AJAX request succeeded. Response: ', response);
$('#' + formId + ' #field_id_757').val(response)
$('#' + formId)[0].submit()
},
error: function (jqXHR, textStatus, errorThrown) {
console.log('AJAX request failed. Status: ', textStatus, '. Error: ', errorThrown);
}
})
})
})

//The get_auth_function is another code snippets function:

function get_auth_code() {
error_log('get_auth_code function triggered');
$username = 'username_is_here';
$password = 'password_is_here';
$login_url = 'https://target_sign_in_url/api/v2/auth/sign_in';

// Login request
$login_response = wp_remote_post($login_url, array(
'body' => array(
'username' => $username,
'password' => $password,
)
));

// Get the HTTP status code of the response
$status_code = wp_remote_retrieve_response_code($login_response);

// If there was an error with the request itself, log the error and send an error response
if (is_wp_error($login_response)) {
$error_message = $login_response->get_error_message();
error_log('Login request error: ' . $error_message);
wp_send_json_error($error_message);
}
// If the request was successful but returned a non-200 status code, log the status code and response body
elseif ($status_code != 200) {
$response_body = wp_remote_retrieve_body($login_response);
error_log('Login failed. Status code: ' . $status_code . ', Response: ' . $response_body);
wp_send_json_error('Login failed');
}
else {
// If the request was successful and returned a 200 status code, process the response
$login_body = wp_remote_retrieve_body($login_response);
$login_data = json_decode($login_body, true);

if (!isset($login_data['sessionToken'])) {
error_log('Session token not set. Response: ' . $login_body);
wp_send_json_error('Session token not set');
}

wp_send_json_success($login_data['sessionToken']);
}
}

Victor Font replied 1 year ago

I also see that you're not using nonce for security.

This is as far as I can go as a community volunteer. Testing this further requires access to your server, which I can't help with as a community volunteer. If you need a dev's help to solve this, please visit https://formidable-masterminds.com/developers-directory/

Steven MSteven M replied 1 year ago

Thanks Victor.

This was way to complex for this use case.

I solved this by first using the FF app action to login and then grab the response token.

Second in the response capture function grabbed the token and used this to send an the API request function.

Job done!

Victor Font replied 1 year ago

Glad you figured it out.

Making the Best WordPress Plugin even better - Together

Take on bigger projects with confidence knowing you have access to an entire community of Formidable Experts and Professionals who have your back when the going gets tough. You got this!
Join the community
crossarrow-right