Steps to handle Ajax requests with cross-origin resource sharing (CORS

At my localhost, I have a client front end running on port 1841 and a back end on port 9000.

The authentication system I am using involves a simple username/password combination that generates a Json Web Token (jwt).

After the client receives the token, I instruct them to save it in a cookie using JavaScript. However, when the XmlhttpRequest call is made from the client (:1841) to the server (:9000), the request does not contain any cookies. As a result, the server responds with a 401 status code (which is expected behavior). I am aware that this lack of cookie information being sent is due to the SAME-ORIGIN-POLICY.

I am utilizing ExtJS 6 as the client and Node.js as the server.

What steps do I need to configure on both the server side and client side to get this working?

On the server side, I have already enabled CORS requests. I have heard about httpOnly, but I am unsure how to handle it.

Login request from localhost:1841 (ExtJS client):

    Ext.Ajax.request({
        url: 'http://localhost:9000/api/users/authenticate/',
        method: 'POST',
        params: params,
        success: function(response){
            var text = response.responseText;
            var data = Ext.decode(text, true);

            if(data.access_token){
                me.saveToken(data.access_token);
                me.createInterface();
            } else {
                if(data.message){
                    Ext.Msg.alert("Error", data.message);
                } else {
                    Ext.Msg.alert("Error", "Something went wrong.");
                }
            }
        },

CORS configuration:

cors = require('cors');
...
...
... 
var whitelist = ['http://127.0.0.1:9000', 'http://localhost:8080', 'http://localhost:9000', 'http://127.0.0.1:8080', 'http://localhost:1841', 'http://127.0.0.1:1841']
 var corsOptionsDelegate = function (req, callback) {
    var corsOptions;
     if (whitelist.indexOf(req.header('Origin')) !== -1) {
        corsOptions = { origin: true } // reflect (enable) the requested origin in the CORS response
    }else{
        corsOptions = { origin: false } // disable CORS for this request
 }
    callback(null, corsOptions) // callback expects two parameters: error and options
}
...

module.exports = function(app) {
....
app.use(cors(corsOptionsDelegate));

}

Another call from the client:

Ext.ajax.request({
  url : 'http://localhost:9000/api/users/'
  method : 'POST'
  success: function(response){
        var text = response.responseText;
        var data = Ext.decode(text, true);
        ...
        ...
        }
    },
})

Server-side validation:

function isAuthenticated() {
    return compose()
//     Validate jwt
        .use(function (req, res, next) {

            ....
            ....
            console.log(req.headers.authorization);


            validateJwt(req, res, function (err) {

                if (err) {
                    console.log(err.inner.name);
                    if (err.inner.name === "TokenExpiredError") {
                        return next({"error":err.inner.name});
                    }
                }
                next();
            });

    })
    .use(function (req, res, next) {
        ....

        });
    });

Edit 1:

I have implemented Set-Cookie in node, and Set-Cookie appears in the response headers AND in the preview cookies from DevTools. However, the cookies are not being set in the browser.

exports.authenticate = function(req, res, next){
    User.findOne({
        fullName: req.body.username
    }, function(err, user) {
    ....
        if (!user) {
            res.status(401).json({
                success: false,
                message: 'Authentication failed. User not found.'
            });
        } else {
            // Check if password matches

            if(user.authenticate(req.body.password)){
                var access_token = jwt.sign(user, config.secrets.session, {
                    expiresIn: 60 // in seconds
               });

               res.cookie('access_token',access_token);

               res.status(200).json({
                   "success": true,
                   "access_token" : access_token
                   });
            }else{
              ....
            }
        }
    });
}

Answer №1

If you are utilizing ExtJS for Ajax requests, you have the option to utilize the defaultXhrHeader property to send a token from the client side to the server side.

When making an authenticate request to obtain a token, you can make use of ExtJS Cookies to set and retrieve the token or cookies.

Ext.Ajax.request({
     url: 'http://localhost:9000/api/users/authenticate/',
     params: params,
     method: 'POST',
     success: function(response, opts) {
         var data = Ext.decode(response.responseText;);
         if (data.access_token) {
             //Set cookie on the client side using Utility class
             Ext.util.Cookies.set('access_token', data.access_token);
         } else {
             if (data.message) {
                 Ext.Msg.alert("Error", data.message);
             } else {
                 Ext.Msg.alert("Error", "Something went wrong.");
             }
         }
     },
     failure: function(response, opts) {
         console.log('server-side failure with status code ' + response.status);
     }
 });

Now, you must include the same token in your Ajax request by using the defaultXhrHeader configuration.

Here is an example:

Ext.Ajax.request({
     url: 'http://localhost:9000/api/users/',
     method: 'POST',
     //send cookie to server using defaultXhrHeader 
     defaultHeaders: {
         'access_token': Ext.util.Cookies.get('access_token'),
         'Content-Type': 'application/json;charset=utf-8'
     },
     success: function(response, opts) {
         var data = Ext.decode(response.responseText;);
         //Your logic here.
     },
     failure: function(response, opts) {
         console.log('server-side failure with status code ' + response.status);
     }
 });

If you are using NodeJs on the server side, you can retrieve the token from the header.

Answer №2

JavaScript on the client side is restricted to setting cookies for the current domain.

Cookies for different domains will have their own separate sets.

In order to work around this limitation, you can either:

  • Set the cookie from a different origin like :9000 using HTTP or
  • Transfer the information through an alternate method (such as embedding it in a POST request).

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

Convert an array containing arrays of booleans to a single array of booleans (Array<Array<boolean>> to Array<boolean>)

There is an array that contains multiple arrays of booleans, all of the same length. arrBefore = [arr1, arr2, ..., arrn]; The goal is to create a new array that consists of boolean values where each index is true if any of the corresponding indexes in th ...

Failed verification of C-Lang in React-Hardware/Particle

Currently, I am utilizing React, React Hardware ([https://github.com/iamdustan/react-hardware/]), and Johnny-Five along with the Particle Photon. The error stack displayed below is what pops up when executing my lib/app.js file: # Fatal error in ../deps/v ...

Concealing the source code within a Next.js application

Currently, I am utilizing next.js for a project. We have a contact page where we display email addresses in cards, but we want to prevent bots from accessing this information. A solution was discovered by one of my colleagues to hide the email addresses i ...

The Ajax method delivers information on number 1 in the conclusion

When using Ajax, I am receiving HTML code and encountering an issue. At the end of the code, I notice the number 1 (or 11) appears. add_action( 'wp_ajax_nopriv_getCart', 'getCart' ); add_action( 'wp_ajax_getCart', 'getCa ...

Increase the quantity of a product in the cart on Laravel by clicking the "add to cart" button

I have recently started using Laravel and I am trying to implement an 'Add to cart' button that adds the same product to the shopping cart with a quantity of +1. I want to check if the stock is greater than the requested quantity. If the availabl ...

What is the best way to open an already existing tab in Safari using an HTML 'a' link?

Is it possible to return to Safari after launching another app? <a href="webbrowserapp://example.com/open?url=http.....">Open WebBrowserApp</a> I've tried using: <a href="safari://">Return to Safari</a> It would be ideal if ...

The click event is failing to trigger because of the alteration in the width of the table cell

I've encountered a unique issue - I'm working with a <table> where each <td> contains a text box as well as an add button in the following cell. The text box includes an onblur function that hides the textbox and generates a <span& ...

Is there a way to use AJAX in Django to update a table linked with JavaScript after uploading a file?

Here is a visual representation of the table before and after file upload: https://i.sstatic.net/9jXiC.png After the file upload using AJAX, the table must refresh dynamically with the updated data: https://i.sstatic.net/IWzWP.png Issue: Following a succ ...

Resizing the parent container when the height of its absolutely positioned children is unknown and dynamic upon window resize

https://codepen.io/umbriel/pen/MxazRE One interesting feature of my slideshow is that users can change the slide by swiping their mouse cursor horizontally over the slide container. Since the children (slides) are absolutely positioned, I faced a challen ...

Using jQuery to create an AJAX request for a basic website

I created a website where users can enter an access code to reveal a secret message, and it's working perfectly. Now, I want to enhance it by automatically sending an email to the user once the secret message is revealed. I plan to use ajax to call ...

The pdf2json encountered an error when attempting to process a PDF file sent via an HTTP

I am encountering an issue while attempting to extract information from PDF files using a nodejs script. Upon running the program, I encounter the following error: Error: stream must have data at error (eval at <anonymous> (/Users/.../node_modules/ ...

Adding a space after a comma automatically upon saving changes in VSCode

Whenever I input code (t,s) into the system and make changes to it, it automatically transforms into (t, s) with an added space after the comma. Is there a way to avoid VScode from adding this extra space on its own? ...

Issue encountered when trying to import an image URL as a background in CSS using Webpack

I have been trying to add a background image to my section in my SCSS file. The linear gradient is meant to darken the image, and I'm confident that the URL is correct. background-image: url(../../assets/img/hero-bg.jpg), linear-gradient(r ...

Troubles with transferring data into a BigQuery table through a cloud function

I am encountering difficulties while attempting to load a Data store backup into an existing table in BigQuery. The error message I receive is: TypeError: bigquery.dataset(...).table(...).load is not a function I am following one of the examples from the ...

How to retrieve the siblingNode value using jQuery

Looking to retrieve a sibling's value - here is my code: <table class="item-result-table" > <tr class="class-tr"> <td class="class-td"><label class="class-lbl">labeldata1</label></td> <td><label>l ...

Does Visual Studio Code support custom procedural import paths for JavaScript intellisense?

I am looking to implement JS (ESM) intellisense for vscode within the Firefox codebase for a specific distribution of Firefox. Within Firefox, I need to register modules in build scripts like moz.build and import them using paths such as "resource://gre/m ...

Obtaining a user id by clicking on a checkbox and then a button in Vue JS

My goal is to create user-specific checkboxes where clicking on a checkbox will allow the user ID to be retrieved using the getUserId method upon clicking the "Get user id" button. To see the code in action, visit this CodeSandbox link <template> ...

Error encountered with STRIPE PAYMENT GATEWAY: "Customer cus_xxxx is missing card with ID tok_visa"

// client side code const onToken = async (token) => { console.log(token); const bookingDetails = { room, userid: JSON.parse(localStorage.getItem("currentUser"))._id, fromdate, todate, totalAmount, totaldays: totalDays, token, }; try { ...

Encountering a Typescript TypeError in es2022 that is not present in es2021

I'm attempting to switch the target property in the tsconfig.json file from es2015 to es2022, but I am encountering an error while running tests that seem to only use tsc without babel: Chrome Headless 110.0.5481.177 (Mac OS 10.15.7) TypeError: Can ...

Exploring the connections: Using Facebook's Graph API to access friends of

When utilizing the Facebook Graph API (https://developers.facebook.com/tools/explorer), I encountered an issue while querying the "friends" field of my friends. The response consistently displays: { "error": { "message": "Unsupported operation", ...