简体   繁体   English

生产中的Axios拦截器问题

[英]Axios interceptor issue in production

I am experiencing an issue when developing an application and attempting to utilize a refresh token. 开发应用程序并尝试使用刷新令牌时遇到问题。 I am using ADFS for authentication, where I get an id_token that expires every hour and a refresh token that lasts 8 hours. 我正在使用ADFS进行身份验证,在这里我得到一个ID_token(该令牌每小时都会过期)和一个刷新令牌(会持续8小时)。

In development, the below script works perfectly as intended and reaches out to the server for a refresh. 在开发中,以下脚本可以按预期完美运行,并可以刷新服务器。

In production, it gets new tokens, but it never retries the original request. 在生产中,它会获得新的令牌,但不会重试原始请求。 I am trying to find out why it is different on webpack-dev-server vs production. 我试图找出为什么webpack-dev-server与production上的区别。

Any help would be much appreciated! 任何帮助将非常感激!

PS Using Babel Presets: babel-preset-env and babel-preset-stage-2 PS使用Babel预设:babel-preset-env和babel-preset-stage-2

axios.js axios.js

import axios from 'axios'

// Set baseURL for development and production
const baseURL = process.env.NODE_ENV === 'development' ? '//localhost:3001/api' : '/api'

// Create instance of axios with correct baseURL
const instance = axios.create({
  baseURL
})

// Intercept responses
instance.interceptors.response.use((response) => {
  return response
}, async (error) => {

  // Pull config, status and data from the error
  const { config, response: { status, data } } = error

  // Pull tokens from local storage
  let currentTokens = JSON.parse(localStorage.getItem('tokens')) || null

  // If response errors at 401, token is still valid and we have tokens in localStorage
  if(status === 401 && data.token_invalid === undefined && currentTokens && !config._retry) {
    config._retry = true

    try {
      // Ask server for new token
      const authenticate = await instance.post('/user/login', {refresh_token: currentTokens.refresh_token})

      // Pull tokens and success from authenticated request
      const { tokens, success } = authenticate.data

      // If successful, set access_token, id_token, headers and localStorage      
      if(success) {
        currentTokens.access_token = tokens.access_token
        currentTokens.id_token = tokens.id_token

        const bearer = `Bearer ${tokens.id_token}`
        config.headers['Authorization'] = bearer
        Object.assign(instance.defaults, {headers: {Authorization: bearer}})

        localStorage.setItem('tokens', JSON.stringify(currentTokens))

        // Rerun original request
        return instance(config)
      }
    } catch (e) {
      // Catch any errors
      console.log(e)
      return
    }
  } else if(data && data.token_invalid !== undefined && data.token_invalid) {
    // If refresh has expired, take user to ADFS to reauthenticate
    location = `${process.env.OAUTH_CLIENT_EP}?client_id=${process.env.AZURE_CLIENT_ID}&redirect_uri=${process.env.REDIRECT_URI}&resource=${process.env.REDIRECT_URI}&response_type=code`
    return
  } else {
    // Console log all remaining errors
    return
  }
})

export default instance

Found the issue. 找到了问题。 It appears that since I'm using both relative and absolute urls for the baseURL, the absolute URL in development is being processed correctly, however the relative URL is being chained to the original request. 看来,由于我同时使用了相对URL和绝对URL作为baseURL,因此正在开发中的绝对URL已得到正确处理,但是相对URL已链接到原始请求。

In other words, sending in production, the url looks like: /api/api/actual/request, where it should just be /api/actual/request. 换句话说,在生产环境中发送时,URL看起来像:/ api / api / actual / request,其中应该只是/ api / actual / request。

I solved this by adding a API_URL to my config files, and input the absolute url for both development and production and the updated my instance creation to the following. 我通过在配置文件中添加API_URL来解决此问题,然后输入用于开发和生产的绝对URL,并将实例创建更新到以下内容。

const instance = axios.create({
  baseURL: process.env.API_URL
})

Thanks to all who viewed and attempted to help. 感谢所有查看并尝试提供帮助的人。 Have a great day everyone! 祝大家有个美好的一天!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM