Axios拦截器问题在生产中

时间:2018-02-06 03:37:23

标签: javascript authentication axios interceptor refresh-token

我在开发应用程序并尝试使用刷新令牌时遇到问题。我使用ADFS进行身份验证,我得到一个每小时过期的id_token和一个持续8小时的刷新令牌。

在开发过程中,下面的脚本可以完美地按预期工作,并可以到服务器进行刷新。

在制作中,它会获得新的令牌,但它永远不会重试原始请求。我试图找出为什么webpack-dev-server与生产有所区别。

非常感谢任何帮助!

P.S。使用Babel Presets:babel-preset-env和babel-preset-stage-2

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

1 个答案:

答案 0 :(得分:0)

发现了这个问题。看来,由于我正在使用baseURL的相对URL和绝对URL,因此正在正确处理开发中的绝对URL,但是相对URL被链接到原始请求。

换句话说,在生产中发送,网址看起来像:/ api / api / actual / request,它应该只是/ api / actual / request。

我通过在配置文件中添加API_URL来解决这个问题,并为开发和生产以及更新后的实例创建输入绝对URL到以下内容。

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

感谢所有观看并试图提供帮助的人。祝每个人都过得愉快!