【问题标题】:Reactjs - logout/redirect user on failed api callReactjs - 在失败的 api 调用上注销/重定向用户
【发布时间】:2018-12-20 13:40:47
【问题描述】:

我使用 Reactjs 构建了一个 Web 应用程序。我使用路由器和 redux 进行身份验证的状态管理。一切正常,但问题在于 api 调用。在用户登录并调用...服务后,我想检查服务的响应是否包含任何令牌问题(例如:令牌已过期)。如果存在令牌问题,我想使令牌无效(删除它)并将用户发送回登录页面并显示错误消息。现在,如果我在我的 redux action/reducer 中执行所有 api 调用,我就可以做到这一点。但我不确定是否必须为每次调用都实现 redux,因为我不需要其他组件中的数据。而且在 redux 中实现所有服务也很耗时,需要大量代码。

我将项目复制到 stackblitz。

https://stackblitz.com/edit/react-auth?file=index.js

场景很简单。单击登录,您就在应用程序中。该应用程序会自动调用服务并获得响应。如果您将 URL 更改为 api.js 中的错误 URL,则此服务将给出“40x”响应。当我收到此响应时,我想将用户重定向到登录页面。

有什么帮助/建议吗?

谢谢。

【问题讨论】:

  • 您应该在服务器端处理令牌:如果身份验证令牌有问题,服务器不应发送 404 而是发送 401。原因是因为 404 并不意味着令牌无效,而是意味着 URL 未找到,请检查 this list。你用什么在客户端上调用你的 api?
  • 其实 '404' 只是一个示例。如何在 401 上重定向用户?
  • 我在答案中添加了axios的代码

标签: reactjs redux react-router react-redux


【解决方案1】:

这是一个使用 axios 和您的 api.js 的示例:

import axios from 'axios';

const apiKey = 'API_KEY';

export async function getWeather() {
  const url = `https://reqres.in/api/users?page=2`;
  axios.interceptors.response.use(handleSuccess, handleError)
  return await axios.post(url);
 }

function handleSuccess(response) {
  console.log('success');
  return ({data: response.data});
}

function handleError(error) {
  if (error.message === 'Network Error') {
     // The user doesn't have internet
      return Promise.reject(error);
   }
   switch (error.response.status) {
      case 400:
        break;
      case 401:
        // Go to login
        break;
      case 404:
        // Show 404 page
        break;
      case 500:
        // Serveur Error redirect to 500
        break;
      default:
        // Unknow Error
       break;
    }
    return Promise.reject(error);
}

因此,根据代码状态和​​您希望代码答案的行为,您应该重定向用户或只向他显示一个模式。

查看axios interceptors上的文档

【讨论】:

  • 希望对您有所帮助,您需要了解的是,每个 axios 实例上都有拦截器,当您希望成功请求和失败请求的行为始终相同时,您应该使用它。
  • 感谢您的回答。现在在案例 401 中,您编写了“Go to login”。我将如何实现这一目标。我不确定如何调用 dispatch({type: AUTH_ERROR, payload: 'Invalid login credentials'}); **或 **this.props.history.push('/login'); 在 api.js 中,不会出现错误。如果我能实现它来引导用户登录并删除令牌,我的问题就解决了。 :)
  • 你可以在 api.js 中使用import { browserHistory } from 'react-router' browserHistory.push('/login')
  • 或者您可以将 axios 实例包装在一个类中,并在创建 api 实例时传递dispatch,这样您就可以从那里分派一个动作。
  • 您能否举一个“将 axios 实例包装在一个类中并传递调度”的示例。我相信这会解决我的问题。谢谢!
【解决方案2】:

我知道这很老,但我正在尝试做与 shotofcode 相同的操作,但使用 fetch 而没有 redux(基本上是因为我在其他任何地方都不需要它)。当我的服务器以“401 Unauthorized”响应时,我能够从服务重定向到登录页面,但我无法从那里返回错误消息。

我能想到的一个可能的解决方案是将错误消息保存在 localStorage 中并在登录页面中获取它。另一种选择是在组件级别捕获并处理错误,但会破坏使用服务的目的并暗示重复很多代码。

有没有人找到更好的解决方案?

【讨论】:

    猜你喜欢
    • 2015-02-17
    • 2020-08-17
    • 1970-01-01
    • 2020-03-26
    • 2018-07-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多