在获取调用之前从 AsyncStorage 读取令牌

Reading token from AsyncStorage before a fetch call

在我的 ReactNative 应用程序中,我试图想出一个很好的模式来读取我存储在 AsyncStorage 中的 access_token 并在 [=16= 中使用它] 打电话。

换句话说,我想创建一个使用某种包装器的模式,确保 fetch 调用始终具有它需要的 access_token。所以执行顺序应该总是:

Invoke Fetch Call -> Get Token from AsyncStorage and Prep Header -> Execute Fetch Call

我想出了以下代码,但看起来我在 AsyncStorageAsync 部分遇到了问题,而且我的 fetch 调用在没有令牌的情况下发出。

这是我的 fetch 电话:

export const someApiCall = (request) => {

   const url = 'https://myapi.com/add';

   return (dispatch) => fetch(url, fetchOptionsPost(request))
        .then((response) => {

            if (response.ok && response.status === 200) {

                // Got data. Dispatch some action

            }
        })
}

在这里,我使用辅助函数来准备 headers,等等。下面是 fetchOptionsPost() 的样子:

export const fetchOptionsPost = (request) => {

    getAccessToken()
        .then(token => {

            return {
                method: 'POST',
                mode: 'cors',
                headers: {
                    "Content-Type": "application/json",
                    "Authorization": "Bearer " + token
                },
                body: JSON.stringify(request)
            }
       });
};

getAccessToken() 函数只是从 AsyncStorage 读取它,如下所示:

export const getAccessToken = async () => {

    return await AsyncStorage.getItem("access_token");
}

此模式无效,API 呼叫在没有令牌的情况下发出。

我还想提一下,如果我 hard-code 我的 fetchOptionsPost() 方法中的令牌,一切正常。显然,这里的问题是 fetchOptionsPost() 没有返回任何东西。

我该怎么做才能确保我的令牌始终在我的 fetchOptionsPost 中?

您可以在 someApiCall 函数中添加 token 调用。并在函数内部创建选项。函数是异步的,所以在获取令牌结果

后仅获取 运行

已更新

const fetchOptionsPost = (token) =>{
  return ({
    method: 'POST',
    mode: 'cors',
    headers: {
      "Content-Type": "application/json",
      "Authorization": "Bearer " + token
    }
  })
}

export const someApiCall = async(request) => {
  const token = await AsyncStorage.getItem("access_token");
  const url = 'https://myapi.com/add';

  fetch(url, fetchOptionsPost(token))
    .then(response=>response.json())
    .then((data)=>{
       // call the dispatch here
      })
}

为什么在main函数里面使用async

AsyncStorage 只有异步回调。如果您将 AsyncStorage 设置为单独的函数,您应该为两者调用异步 function.Thats 为什么我在父异步函数中添加 with 并将令牌传递给 fetchOptionsPost

这是我想出的,似乎工作正常。我仍然会感谢对此代码的任何建议或改进。

首先,这是我的 fetch 通话现在的样子。我将它包装在 getAccessToken() 函数中,这是一个 async 调用,但因为我使用的是 redux-thunk,所以我能够做到这一点。

export const someApiCall = (request) => {

   const url = 'https://myapi.com/add';

   return (dispatch) => getAccessToken()
        .then(token => {
            fetch(url, fetchOptionsPost(request, token))
                .then((response) => {

                     if (response.ok && response.status === 200) {

                          // Got data. Dispatch some action

                      }
                 })
        })
}

我稍微更改了我的 fetchOptionsPost() 辅助函数,它现在接受令牌。它现在也更强大了。如果它没有获得令牌,它会简单地省略 header 中的 Authorization 部分。我选择了这种方法,因为某些对 API 后端的调用不需要身份验证。此外,isValidString() 是我创建的另一个辅助验证函数,以确保我确实获得了有效的字符串。它 returns TRUEFALSE 响应基于输入的字符串值:

export const fetchOptionsPost = (data, token = null) => {

    if (isValidString(token)) {

        return {
            method: 'POST',
            mode: 'cors',
            headers: {
                "Content-Type": "application/json",
                "Authorization": "Bearer " + token
            },
            body: JSON.stringify(data)
        }
    } else {

        return {
            method: 'POST',
            mode: 'cors',
            headers: {
                "Content-Type": "application/json"
            },
            body: JSON.stringify(data)
        }
    }
};

最后,getAccessToken() 函数并没有真正改变,但它是:

export const getAccessToken = async () => {

    return await AsyncStorage.getItem("access_token");
}

如我所说,对于进一步改进此代码的任何评论或建议,我将不胜感激。

希望这对其他人有用。

使用 Async 和 await 方法并在每次调用之前获取令牌。

async ()=>{
let token =await getTokenFromLocal();
return (dispatch) => fetch(url, fetchOptionsPost(request))
        .then((response) => {

            if (response.ok && response.status === 200) {

                // Got data. Dispatch some action

            }
        })
}