首页 > 解决方案 > axios 拦截器请求未获取异步存储 access_token 并且为空?

问题描述

在 react-native 中,我使用@react-native-async-storage/async-storage保存 access_token,我的逻辑是:当用户登录成功时,保存 access_token。并请求其他api axios拦截器请求,从存储读取access_token和axios.headers[Authorization] = access_token,但我发现axios没有从存储中获取access_token。

例如:登录成功时,保存access_token,重定向到首页。在首页请求/userinfoswiperapi中,现在axios拦截器请求并从存储中获取access_token。

function getStorageToken() {
  // getAccessToken is async

  getAccessToken().then(value => {
    access_token = value
  })
  return access_token
}

const service = axios.create({
  baseURL: '/',
  timeout: 60000,
  headers: {
    'Authorization': 'Bearer ' + getStorageToken()
  }
})

但我发现reqeust /userinfo/swiperaccess_token为空,getStorageToken()打印access_token。和 getStorageToken() 之后/userinfo/swiper。所以我猜当 axios 拦截器请求 api 存储不返回 access_token 时。

如何解决此错误?请帮帮我,谢谢!!!

import axios from 'axios'

// 获取storage的access_token
function getStorageToken() {
  getAccessToken().then(value => {
    access_token = value
  })
  return access_token
}

// 获取storage的refresh_token
function getStorageRefreshToken() {
  let refresh_token = null
  getRefreshToken().then(value => {
    refresh_token = value
  })
  return refresh_token
}

// 创建实例
const service = axios.create({
  baseURL: '/',
  timeout: 60000,
  headers: {
    'Authorization': 'Bearer ' + getStorageToken()
  }
})

// 用旧refresh_token获取新的access_token和refresh_token
function refreshToken(refreshToken) {
  return service.post('/refresh_token', {
    refresh_token: refreshToken
  }).then(res => {
    return res.data
  })
}

let isRefreshing = false
let requests = []

// 请求拦截的时候token一直为null
service.interceptors.request.use(config => {
  if (config.headers['Content-Type']) {
    return config.headers['Content-Type']
  } else {
    config.headers['Content-Type'] = 'application/x-www-form-urlencoded;charset=UTF-8'
  }
  return config
}, error => {
  return Promise.reject(error)
})

service.interceptors.response.use(response => {
  console.log('response', response.data)
  const {code} = response.data
  if (code === 2) {
    const config = response.config
    if (!isRefreshing) {
      isRefreshing = true
      const _refreshToken = getStorageRefreshToken()
      return refreshToken(_refreshToken).then(res => {
        const {access_token, refresh_token} = res.data
        service.setToken(token, refresh_token)

        config.headers['Authorization'] = `Bearer ${access_token}`
        config.baseURL = ''
        requests.forEach(cb => cb(access_token))
        requests = []
        return service(config)
      }).catch(err => {
        navigator('Auth')
        return err
      }).finally(() => {
        isRefreshing = false
      })
    } else {
      return new Promise(resolve => {
        requests.push(token => {
          config.baseURL = ''
          config.headers['Authorization'] = `Bearer ${token}`
          resolve(service(config))
        })
      })
    }
  } else if (code === -1) {
    clearAllStorage()
    navigator('Auth')
  }
  return response.data
}, err => {
  return Promise.reject(err)
})

export {service as axios}

获取存储刷新令牌:

const getRefreshToken = async () => {
  try {
    const refreshToken = await AsyncStorage.getItem('refresh_token')
    return refreshToken !== null ? refreshToken : null
  } catch (error) {
    return error    
  }
}

标签: reactjsaxios

解决方案


推荐阅读