@react-native-async-storage/async-storage在axios拦截器中获取token为null?

发布于 2022-09-12 22:50:13 字数 2920 浏览 8 评论 0

在react-native中我用async-storage来存储token, 具体的逻辑是这样:
登陆成功后存储access_token, 然后用axios来拦截请求, 拦截的时候从storage中获取access_token. 接着设置请求头axios.headers[Authorization] = access_token.

我测试的时候发现access_token存储成功, 但是拦截器拦截请求的时候access_tokennull, 比如在首页我调用/userinfo, /swiper等接口发现拿不到access_token. 也就是说获取不到storage中的access_token. 但是最后getStorageToken却打印出了access_token.

由于async-storage存储和读取都是异步的, 所以我怀疑是不是axios拦截器在拦截的时候token还未读取完成, 所以axios.headers[Authorization] = null.

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}

我该如何解决axios拦截请求的时候从storage中获取到access_token

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

零度° 2022-09-19 22:50:13

你需要在请求前获取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 => {
  config.headers['Authorization']= 'Bearer ' + getStorageToken()
  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}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文