Ajax request encountering issues with OIDC SSO redirection, causing query failure

I am curious about how to handle ajax failures caused by OIDC SSO redirect/refresh. It can be tricky because the failure happens silently, giving the impression that everything is functioning correctly.

My website consists of static HTML and basic javascript that uses ajax to populate and refresh the page periodically.

Both the webpage and JS are protected by the same OIDC SSO for access control. However, there are scenarios where the ajax call fails with a 401 error due to needing an authentication refresh (not full password authentication).

Both the backend and frontend are hosted on the same server using Apache with identical Access Control and Authorization requirements.

  1. If a user loads a cached version of the HTML and only the ajax request is triggered (e.g., using the back button).
  2. If the page remains idle for a certain period, I suspect that even regular refreshes may fail for the same reason.

I have implemented a workaround shown below, but it seems like a makeshift solution, and I believe there must be a better standard practice for handling this issue.

// This function runs every 30 seconds
function updateData(args, callback) {
    $.ajax({
        xhrFields: { withCredentials: true },
        url: "/getit?" + args,
        success: function(data) {
            localStorage.removeItem('pagereloaded')
            callback(data);
        },
        statusCode: {
            // Reload is needed when SSO tokens expire, causing ajax failure.
            // If it's just an auth failure, we don't want to create an infinite reload loop.
            // So 'pagereloaded' and timers are used to avoid continuous reloading.
            401: function () {               
                if (localStorage.getItem('pagereloaded') == null || (Date.now() - start_time) > 60000) {
                    localStorage.setItem("pagereloaded", 1)
                    location.reload();
                }
            }
        }
    });
}

Answer №1

WEB AND API MODULES

It appears that the module you are using with Apache is designed specifically for handling website requests, not direct API requests. A recommended approach is to use separate modules tailored for each type of request:

PATH: https://example.com/www/** --> utilizes an OIDC module for web requests credential verification

PATH: https://example.com/api/** --> utilizes an OAuth module for API requests credential verification

Various Apache modules cater to security needs for both web and API requests.

BEHAVIOUR

An API module should allow clients to differentiate between

missing, invalid, or expired API credentials
errors (generally categorized as 401s) from other types of errors. In typical scenarios, 401 errors occur when access or refresh tokens expire, or cookie encryption/token signing keys are updated. These error instances are temporary and can be resolved by re-authenticating the user.

Other error types should return distinct status codes to the client like 400 or 500, prompting an error message display. For instance, if a client secret is incorrectly configured, it results in a permanent error where re-authentication does not resolve the issue but leads to a redirect loop instead. Thorough testing of these error scenarios ensures correct behavior.

UPDATED CODE

To address this, you can implement simple code such as the following example. The client-side code has control over post-401 behavior, deciding whether to reload the page or suspend background requests.

function updateData(args, callback) {
    $.ajax({
        url: "/api/getit?" + args,
        success: function(data) {
            callback(data);
        },
        statusCode: {
            401: function () {               
                location.reload();
            }
        }
    });
}

Moreover, the withCredentials flag is necessary only for cross-origin requests (e.g., https://www.example.com to https://api.example.com). Given your same domain setup, omitting this flag from the code suffices.

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Sending JSON data using AJAX in PHP is a common task that many developers

Upon clicking the delete button, the confirmDelete function is called and it posts the parameters as JSON. The response comes back from the server page and enters the success method, but with a blank string value instead of null. I am unable to identify th ...

Assistance with transforming XML into a personalized JSON format using Node.js

Currently, I am in the process of developing a custom XML to JSON function that is tailored to convert our unique XML structure into a specific JSON format. Despite trying various libraries, I have concluded that transforming the XML into a DOM tree and pe ...

The useEffect hook is executed only once and will not fetch data again upon refreshing the page

There's this component in my project that fetches data from a website and attempts to extract its keys. The issue I'm facing is that it functions correctly the first time, but upon refreshing the page or saving the project in VSCode (which trig ...

What could be causing the jQuery click function to fail on following pages of the dataTable?

I created a code that generates a list of topics with delete and edit buttons within a datatable. Display.php <table data-toggle="table" class="table table-striped table-hover"> <thead> <tr> ...

creating a promise within a .then() function to pass along for future use in a different function

Currently, I am utilizing a native script firebase plugin that requires the following function: getCompanyValue() { var value; firebase.getValue('/companies') .then(result => { console.log(JSON.stringify(result ...

Exploring JSON Object with ng-disabled in AngularJS

One unique feature of my web application is the ability to add new users (username + password) through a form. To prevent duplicate usernames, I have a JSON object called l_usernames defined in a controller named UsersController. This object contains all u ...

Add a fresh item into an array in Json between existing elements

After looping through a JSON object using foreach, the output is as follows: {"Comment": {"id":"1","post_id":"31","created":"14263241"} , "User": {"fname":"Test","lname":"Test2"} } {"Comment": {"id":"2","post_id":"32","created":"14263257"} , "User": {"f ...

A guide to integrating CSS3 transition callbacks with jQuery.ajax

When it comes to making an AJAX request using jQuery, I've been using the following code snippet: $.ajax({ url: page, context: $(pageContent), beforeSend: function(){ $(pageContent).css('opacity', '0'); }, ...

How to submit a form in Spring MVC without causing page refresh

Is there a way to keep the data in listbox2 after submitting the form? Currently, when I submit the form, I lose the data in listbox2 and have to reselect everything again. <form:form action="choseElement" method="post"> <select name="listbox1 ...

The Problem with AJAX Error Handling Customization

Upon loading my webpage using Code Igniter and PHP, the JSON encoded query is returned successfully with data. I have managed to handle the scenario where no records are found by encoding a response in JSON format. However, I am unsure of how to transmit t ...

Calculate the sum of multiple user-selected items in an array to display the total (using Angular)

Within my project, specifically in summary.component.ts, I have two arrays that are interdependent: state: State[] city: City[] selection: number[] = number The state.ts class looks like this: id: number name: string And the city.ts class is defined as f ...

What is the best way to set a default value for a "please select" option using

I am using ng-options to generate select options and the controls values/options are stored in a CA.JSON file. For the VehicleYear option, I would like to include a default "Please select" option. <select> <option value="">Please select</o ...

Sorting arrays in javascript

My JavaScript array is structured like this: var data_tab = [[1,id_1001],[4,id_1004],[3,id_1003],[2,id_1002],[5,id_1005]] I am looking to organize and sort them based on the first value in each pair: 1,id_1001 2,id_1002 3,id_1003 4,id_1004 5,id_1005 ...

Live highstock chart showcasing multiple series

Currently, I have successfully implemented a real-time live graph with one series, following a tutorial similar to the example provided on this page. Below is my JavaScript code: <script> var chart; function requestData() { $.ajax({ url ...

What could be the reason for encountering a 422 Error when transitioning from JQuery AJAX to Fetch?

Currently in the process of transitioning a small FastAPI web app from using JQuery AJAX to the Fetch API. The previous AJAX call involved sending some JSON data to the server and processing it through a backend function. Here is the original JQuery code: ...

Extracting JSON information from the callback function

Can the msg variable in JavaScript be returned from the callback function? I attempted to do so, but received a null value, even though msg contained data within the scope of the callback function. var msg = load(); function load() { $.ajax({ ...

Enhance the style of your React components with React-addons-css-transition

Currently, I am working on creating tabs in React JS and incorporating animations using React-addons-css-transition-group. The code snippet I have written for this purpose is as follows: render() { let view = this.state.tiresView ? this.renderTiresV ...

What causes the second parameter of the function to always appear as "never"?

I am looking to create a simple generic interface for a function that accepts an object's interface, where the first argument is the key of the object and the second argument is another key within that object. Here is my proposed solution: type Test& ...

The CSRF token is required for this action to be completed

Just recently, I discovered how to set up a web server on a Raspberry Pi using Django. I'm in the process of enhancing it by integrating JS to generate a form every time data is sent. However, I've encountered an error that I haven't been ab ...

How can you start a jQuery script following a triumphant Ajax callback?

Having some trouble getting jQuery to execute after a successful Ajax response. Even though I have it in the success callback, it doesn't seem to be working as expected. I came across a potential solution here, but I'm having difficulty understan ...