Home > database >  Node Axios Create Global Token Variable for Use in Separate Variable Header
Node Axios Create Global Token Variable for Use in Separate Variable Header

Time:10-28

Using Node & Axios

What I Want to Do

In my server.js file, I want to call an api for a token that always changes, use axios (or other solution) to create a global token variable, and provide the global token to an app.get request header within an object, again, all within my server.js file.

What I'm Trying

I get the data using...

var data = '<tsRequest>\r\n\t<credentials name="name" password="pword">\r\n\t\t<site contentUrl="" />\r\n\t</credentials>\r\n</tsRequest>';

var config = {
  method: 'post',
  url: 'https://url.uni.edu/api/3.13/auth/signin',
  headers: { 
    'Content-Type': 'text/plain'
  },
  data : data
};

I try to create the global token variable (this is where I'm struggling)...

const token= axios(config)
.then((response) => {
  console.log(response.data.credentials.token);
}).catch((err) => {
  console.log(err);
});

console.log(token)

I have a functioning app.get request where instead of manually providing the token, I want to use the const token...

app.get('/gql', async (req, res) => {
    var someObject = {
      'method': 'POST',
      'url': 'https://diffurl.uni.edu/api/metadata/graphql',
      'headers': {
        'X-Some-Auth': token,
        'Content-Type': 'application/json'
      },

The Current Results

What I have for the var data = and the var config = and the axios(config) all work to return the token via console.log, but I have 2 issues using axios.

The Axios Issues

  1. In my hopes of creating a global token variable, I only understand how to get a console.log result instead of returning a 'useful data object'. In just about every piece of documentation or help found, the example uses console.log, which is not a practical example for learners to move beyond just returning the data in their console. What do I need to provide in axios to create a global token object in addition to or instead of console.log?

  2. I realize 1. is my current blocker, but if I run my app, I get the following:

Promise { <pending> }
Express server running on port 1234
abc123 [the console.logged token via axios]

I'm not sure what the Promise { <pending> } means, how do I fix that?

Beyond The Axios Issues

If the axios problem is fixed, am I passing the const token correctly into my app.get... var someObject... headers?

Thank you for any help you can provide.

CodePudding user response:

if you want to create a to send the token with every request in axios you should create a custom axios instance or change the global axios default you will find the way to do it here, about promise problem you need to resolve it using .then

this how i think you should do it

// first create axios instance
// you can set config defaults while creating by passing config object see the docs
const instance = axios.create();
// then get the token from API
axios(config).then(response=>{
instance.defaults.headers.common["header you want to set"]=response.data.credentials.token
});
// then use the instance to make any request you want that should have the token

CodePudding user response:

This is what Axios interceptors are for.

You can create an Axios instance with an interceptor that waits for the token request to complete before adding the token to the outgoing request.

A response interceptor can be added to handle 401 statuses and trigger a token renewal.

const data = "<tsRequest>...</tsRequest>";

let renew = true;
let getTokenPromise;

const renewToken = () => {
  if (renew) {
    renew = false; // prevent multiple renewal requests
    getTokenPromise = axios
      .post("https://url.uni.edu/api/3.13/auth/signin", data, {
        headers: {
          "content-type": "text/plain", // are you sure it's not text/xml?
        },
      })
      .then((res) => res.data.credentials.token);
  }
  return getTokenPromise;
};

const client = axios.create();

// Request interceptor to add token
client.interceptors.request.use(async (config) => ({
  ...config,
  headers: {
    "X-Some-Auth": await renewToken(),
    ...config.headers,
  },
}));

// Response interceptor to handle expiry
client.interceptors.response.use(
  (res) => res,
  (error) => {
    if (error.response?.status === 401) {
      // Auth expired, renew and try again
      renew = true;
      return client(error.config);
    }
    return Promise.reject(error);
  }
);

// if putting this in a module...
// export default client;

The first time you try to make a request, the token will be retrieved. After that, it will continue to use the last value until it expires.

  • Related