使用授权标头的react-native fetch有时会返回401

问题描述 投票:1回答:1

我正面临一些问题,我有时会从手机上获取状态码401(未经授权)。我正在尝试从我的计算机localhost(192.168.0.7)访问API。

我有一个屏幕,当我点击一个按钮时,它将导航到一个页面,它将通过API请求数据。当我再次返回并导航到同一页面时,有时会返回代码401。

因此,如果我重复相同的步骤(导航并返回),请说10次。我有5-7次未经授权。

以下是我的代码

export function getMyCarpool(param,token) {
    return dispatch => {   
        var requestUrl = _api + 'GetMyProduct?' + param;
        fetch(requestUrl, {
            method: "get",
            headers: new Headers({
                'Accept': 'application/json',
                'Content-Type': 'application/x-www-form-urlencoded',
                'Authorization': 'Bearer ' + token
            })
        })
        .then((request) => {
            console.log(request);
            if(request.status == 200)
                return request.json();
            else if(request.status == 401) {
                //dispatch(logout());    
                throw new Error('Unauthorized access.');
            }
            else 
                throw new Error('Failed to request, please try again.');
        })
        .then((response) => {
            var message = response.message;
            if(response.success == 'true') 
                dispatch({ message, type: GET_MY_PRODUCT_SUCCESS });
            else
                dispatch({ message, type: GET_MY_PRODUCT_FAILED });
        })
        .catch(error => { 
            var message = error.message;
            dispatch({ message, type: GET_MY_PRODUCT_FAILED }); 
        });
    }

我已经检查了手机中的令牌,并尝试使用邮递员提出许多请求。所以我不认为这是服务器方面的问题。

我正在使用Laravel并使用laravel passport进行API身份验证。如果我继续访问很多次,我不确定为什么会发生这种情况,非常感谢任何帮助。

UPDATE ::我正在尝试捕获http请求是否具有来自此link的令牌,我不再遇到问题了。

laravel react-native laravel-5
1个回答
0
投票

这是令牌到期的健康机制。也许你有你的令牌(access_token) 5分钟,然后令牌过期,你应该使用refresh_token重新获得另一个新的令牌(access_token)

有关代码说明:

async function fetchService(url) {
  const reqSetting = {
    headers: {
      Accept: 'application/json',
      Authorization: `Bearer ${Auth.access_token}`,
    },
  };
  const prevRequest = { url, reqSetting };
  const resp = await fetch(url, reqSetting);
  if (!resp.ok) {
    const error = new Error(resp.statusText || 'Request Failed!');
    if (resp.status === 401 || resp.status === 400) {
      const responseClone = resp.clone();
      const errorInfo = await resp.json();
      if (errorInfo.error == 'invalid_token') {
        // console.log('Token Expired', errorInfo);
        try {
          await refreshToken();
          const response = await fetchService(prevRequest.url);
          return response;
        } catch (err) {
          // handle why not refresh a new token
        }
      }
      return responseClone;
    }
    error.errorUrl = url;
    error.code = resp.status;
    throw error;
  }
  return resp;
}

刷新令牌功能的位置是:

async function refreshToken() {
  const url = 'https://example.com/oauth/token';
  const data = {
    grant_type: 'refresh_token',
    refresh_token: Auth.refresh_token,
  };
  try {
    const res = await fetch(url, data);
    const data = res.json();
    Auth.access_token = data.access_token;
    Auth.refresh_token = data.refresh_token;
    return true;
  } catch (error) {
    throw error;
  }
}

如果旧的过期,fetchService将自动重新获得新令牌,然后处理旧请求。

PS。如果您同时有多个请求,fetchService将需要一些优化。你最好选择另一种重新获得令牌策略,比如saga

© www.soinside.com 2019 - 2024. All rights reserved.