在提取调用之前从异步存储读取令牌



在我的ReactNative应用程序中,我试图想出一个很好的模式来读取我存储在AsyncStorage中的access_token并在fetch调用中使用它。

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

调用获取调用 -> 从异步存储获取令牌和准备标头 ->执行获取调用

我想出了以下代码,但看起来我在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
}
})
}

在这里,我使用辅助函数来准备标头等。以下是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 调用在没有令牌的情况下发出。

我还想提一下,如果我在fetchOptionsPost()方法中对令牌进行硬编码,一切正常。显然,这里的问题是fetchOptionsPost()没有返回任何内容。

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

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

更新

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
})
}

为什么在主函数内部使用异步

AsyncStorage只有异步回调。 如果将 AsyncStorage 设置为单独的函数,则应为这两个函数调用 Async。这就是为什么我在父异步函数中添加并将令牌传递给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()帮助程序函数,该函数现在接受令牌。它现在也更强大了。如果它没有获得令牌,则只需省略标头中的Authorization部分。我选择了这种方法,因为对我的 API 后端的某些调用不需要身份验证。此外,isValidString()是我创建的另一个帮助程序验证函数,以确保我确实获得了有效的字符串。它根据输入的字符串值返回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 ()=>{
let token =await getTokenFromLocal();
return (dispatch) => fetch(url, fetchOptionsPost(request))
.then((response) => {
if (response.ok && response.status === 200) {
// Got data. Dispatch some action
}
})
} 

最新更新