使用 fetch 将 `access_token` 插入到所有 API 调用中

Insert `access_token` into all API calls with fetch

我正在开发 React 应用程序,但我无法找到一种 "clean" 方法来自动验证 API 调用,方法是将 access_token 参数放入应用程序的每个查询中发送。访问令牌存储在 redux store.

我创建了一个 lib 文件来处理所有 API 调用:

const api_server = 'http://site.dev/'
const api_url = api_server + '/app/api'
const api_version = 'v1'
const client_id = '1_xxxxxxxxxxxxxxx'
const client_secret = 'xxxxxxxxxxxxxxxx'

module.exports = {

  getRealtimeFeed: function(page, access_token=''){
    const endpoint = api_url + '/' + api_version + '/posts?'
      + 'limit=6'
      + '&page=' + page
      + '&access_token=' + access_token
    return fetch(
      endpoint,
      { method: "GET", headers: { "Accept": "application/json" }}
    )
  },
}

我发现它很容易在整个应用程序中使用,除了如您所见,我总是需要将访问令牌传递给 api 函数。

然后我在我的 actionCreators.js 文件中使用 api

import SiteAPI from '../lib/site.api'

export function fetchLatestPosts(page, accessToken='') {
  return dispatch => {
    SiteAPI.getRealtimeFeed(page, accessToken)
    .then( (response) => {
      if (response.status === 200){
        response.json().then( (json) => {
          dispatch(fetchedLatestsPosts(json.results))
        })
      } else {
        console.error(response)
      }
    })
  }
}

在我的反应 Component 中,我使用访问令牌调用操作函数,但这意味着我的所有组件都需要访问令牌作为 prop 传递。

我想知道是否有一种方法可以一劳永逸地设置访问令牌供 api 使用,而不是每次我创建 [=] 时都必须传递它33=] 呼叫。 我对 React 和 Redux 还很陌生,所以我想可能有一个我没有正确学习的概念可以让我做这样的事情。

谢谢:)

您可以在 API 文件中导入 redux 存储并使用它来检索 access_token:

import store from './path/to/your/store'

const api_server = 'http://site.dev/'
...

function getAccessToken() {
  return store.getState().access_token // adjust according to your store structure
}

module.exports = {
  getRealtimeFeed: function(page){
    const endpoint = api_url + '/' + api_version + '/posts?'
      + 'limit=6'
      + '&page=' + page
      + '&access_token=' + getAccessToken()
    return fetch(
      endpoint,
      { method: "GET", headers: { "Accept": "application/json" }}
    )
  },
}

编辑

如果你使用redux-thunk那么你可以在你的动作中得到access_token(你可以在redux-thunk动作函数中定义第二个参数getState):

import SiteAPI from '../lib/site.api'

export function fetchLatestPosts(page) {
  return (dispatch, getState) => {
    const accessToken = getState().accessToken
    SiteAPI.getRealtimeFeed(page, accessToken)
    .then( (response) => {
      if (response.status === 200){
        response.json().then( (json) => {
          dispatch(fetchedLatestsPosts(json.results))
        })
      } else {
        console.error(response)
      }
    })
  }
}

我认为这是更好的决定,因为您的 API 方法不应包含 redux 存储逻辑。他们应该只打扰 API 个请求。