0

Trying to do a get request to an endpoint that requires an Auth token. But whenever the request is made - it returns a 401 error ("Authorization header is expected'). The token is retrieved asynchronously from chrome.storage. But doesn't seem to be sent in the ajax request. Any help is appreciated.

ajax: {
      type: "GET",
      beforeSend: async function (request) {
        var token = await bearerToken();
        request.setRequestHeader("Authorization", token);
      },
      url: function (params) {
        return getChannelURL(params.term);
      },
      dataType: "json",
      data: function (response) {
        // data -> entire json object
        return response;
      },
      // data.data -> array containing all the channel elements
      processResults: function (data, params) {
        for (var i = 0; i < data.data.length; i++) {
          data.data[i].text = data.data[i].text || data.data[i].name;
        }
        return {
          results: data.data,
        };
      },
      cache: true,
    },
    minimumInputLength: 1,
    placeholder: "Select a Channel",
    width: "resolve",
    templateResult: formatChannelData,
  });

Below is the function that stores the token

bearerToken = async () => {
    var tokenRetrieved = await helper.getLocalStorage('tokenElement')
    var token = tokenRetrieved.tokenElement
    return ("Bearer "+ token);
}
J. YYY
  • 21
  • 4
  • Have you tried setting `headers: authHeader` where `authHeader = new Headers(); authHeader.append("Authorization", await bearerToken());` in the ajax object? Maybe in both the `beforeSend` and outside it too? – Rojo Apr 30 '21 at 17:10
  • @Rojo tried it, still getting the same error – J. YYY Apr 30 '21 at 17:58
  • Try setting [`request.setRequestHeader` like this answer](https://stackoverflow.com/a/29805115/10210841) – Rojo Apr 30 '21 at 18:04
  • @Rojo set, still not working though. I can't seem to figure out why – J. YYY Apr 30 '21 at 19:52
  • In that answer’s code, you changed basic to bearers, right? – Rojo Apr 30 '21 at 21:14
  • @Rojo Yeah I did - still not sending – J. YYY May 03 '21 at 17:37
  • What does `console.log("Bearer "+ token)` output (does it match the expected token)? – Rojo May 03 '21 at 21:18
  • Also, in the Chrome Developer tools -> Network tab, find the failed request (you might need to reload), Right click the request -> Copy -> Copy Request Headers, and paste it into a text editor. Does it contain the right Authorization token? – Rojo May 03 '21 at 21:23
  • @Rojo whenever I do a console.log, the output matches the expected token exactly. In the developer tools, the authorization token isn't being sent at all - so the failed request's header contains no auth field. – J. YYY May 04 '21 at 13:53
  • It could be because of `await` in the function. Try using `await` outside of the ajax and then use a variable in `beforeSend`. – Rojo May 04 '21 at 13:55
  • @Rojo Tried that, the await requires it to be wrapped in an async function - so the variable won't be accessible when the header calls it - unless another await is in front of it. – J. YYY May 04 '21 at 14:14
  • I don't think I could explain it well. I have added an answer to clear things up. – Rojo May 04 '21 at 14:17

1 Answers1

0

Your AJAX should look like this:

async function sendAJAX() {
var token = await bearerToken();
ajax: {
      type: "GET",
      beforeSend: async function (request) {
        request.setRequestHeader("Authorization", token);
      },
      url: function (params) {
        return getChannelURL(params.term);
      },
      dataType: "json",
      data: function (response) {
        // data -> entire json object
        return response;
      },
      // data.data -> array containing all the channel elements
      processResults: function (data, params) {
        for (var i = 0; i < data.data.length; i++) {
          data.data[i].text = data.data[i].text || data.data[i].name;
        }
        return {
          results: data.data,
        };
      },
      cache: true,
    },
    minimumInputLength: 1,
    placeholder: "Select a Channel",
    width: "resolve",
    templateResult: formatChannelData,
  });
}
}

The function will wait for for the token to be created and then send the AJAX.

Rojo
  • 2,749
  • 1
  • 13
  • 34