节点Axios创建全局令牌变量以用于单独的变量标头

vohkndzv  于 2022-11-05  发布在  iOS
关注(0)|答案(2)|浏览(145)

使用节点和Axios
"我想做的事"
在我的server.js文件中,我想调用一个API来获得一个总是变化的令牌,使用axios(或其他解决方案)来创建一个全局令牌变量,并将全局令牌提供给一个对象中的app.get请求头,同样,所有这些都在我的server.js文件中。
"我在尝试什么"
我得到的数据使用...

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
};

我尝试创建全局令牌变量(这是我遇到困难的地方)...

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

console.log(token)

我有一个正常运行的应用程序。获取请求,而不是手动提供令牌,我想使用const令牌...

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'
      },

当前结果

我所拥有的**var data =var config =以及axios(config)**都可以通过console.log返回令牌,但我在使用axios时遇到了两个问题。

Axios问题

1.我希望创建一个全局令牌变量,但我只知道如何获得一个console.log结果,而不是返回一个“有用的数据对象”。这对于学习者来说不是一个实际的例子,不能超越仅仅在他们的控制台中返回数据。除了console.log之外,我还需要在axios中提供什么来创建全局令牌对象?
1.我意识到1.是我当前的拦截器,但如果我运行我的应用程序,我会得到以下:

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

我不确定Promise { <pending> }是什么意思,我该如何解决这个问题?

超越Axios问题

如果axios的问题得到了解决,我是否将const token正确地传递到了app.get... var someObject... headers中?
谢谢你能提供的任何帮助。

lx0bsm1f

lx0bsm1f1#

这就是Axios拦截器的用途。
您可以创建带有拦截器的Axios示例,该拦截器在将令牌添加到传出请求之前等待令牌请求完成。
可以添加响应拦截器来处理401状态并触发令牌更新。

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;

第一次尝试发出请求时,令牌将被检索。此后,它将继续使用上一个值,直到过期。

zc0qhyus

zc0qhyus2#

如果你想创建一个在axios中发送每个请求的令牌,你应该创建一个custom axios instance或更改全局axios默认值,你会找到这样做的方法here,关于promise问题,你需要使用来解决它。然后
我认为你应该这样做

// 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

相关问题