【问题标题】:react-native fetch with authorization header sometime return 401带有授权标头的 react-native fetch 有时会返回 401
【发布时间】:2018-10-22 20:34:36
【问题描述】:

我遇到了一些问题,有时我会从手机中获取状态码 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 护照进行 API 身份验证。如果我继续访问很多次,我不确定为什么会发生这种情况,非常感谢任何帮助。

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

【问题讨论】:

标签: laravel react-native laravel-5


【解决方案1】:

这是一种健康的令牌过期机制。也许你有你的令牌(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 将需要一些优化。你最好选择其他的return token策略,比如saga

【讨论】:

    猜你喜欢
    • 2015-07-24
    • 2015-01-27
    • 2018-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-11-23
    • 1970-01-01
    • 2017-05-22
    相关资源
    最近更新 更多