【问题标题】:Preventing unauthed ajax requests from redux actions防止来自 redux 操作的未经身份验证的 ajax 请求
【发布时间】:2016-08-29 20:10:19
【问题描述】:

我有一个这样定义的组件。 fetchBrands 是一个 redux 操作。

class Brands extends Component {

  componentWillMount() {
    this.props.fetchBrands();
  }

  render() {
    return (
        // jsx omitted for brevity
    );
  }
}

function mapStateToProps(state) {
  return { brands: state.brands.brands }
}

export default connect(mapStateToProps, { fetchBrands: fetchBrands })(Brands);

这个组件被包装在一个高阶组件中,如下所示:

export default function(ComposedComponent) {
  class Authentication extends Component {

    // kind if like dependency injection
    static contextTypes = {
      router: React.PropTypes.object
    }

    componentWillMount() {
      if (!this.props.authenticated) {
        this.context.router.push('/');
      }
    }

    componentWillUpdate(nextProps) {
      if (!nextProps.authenticated) {
        this.context.router.push('/');
      }
    }

    render() {
      return <ComposedComponent {...this.props} />
    }
  }

  function mapStateToProps(state) {
    return { authenticated: state.auth.authenticated };
  }

  return connect(mapStateToProps)(Authentication);
}

然后,在我的路由器配置中,我正在执行以下操作:

&lt;Route path="brands" component={requireAuth(Brands)} /&gt;

如果本地存储中不存在身份验证令牌,我会重定向到公共页面。然而,fetchBrands 动作仍在被调用,它正在触发一个 ajax 请求。由于缺少身份验证令牌,服务器拒绝了它,但我什至不希望拨打电话。

export function fetchBrands() {
  return function(dispatch) {
     // ajax request here
  }
}

我可以用if/else 检查来包装 ajax 请求,但考虑到我需要在其中执行此操作的所有操作函数,这并不是很干燥。如果身份验证失败,我如何实现一些 DRY 来防止调用在浏览器级别?

【问题讨论】:

    标签: authentication reactjs redux dry react-redux


    【解决方案1】:

    您应该为此编写一个中间件。 http://redux.js.org/docs/advanced/Middleware.html

    由于您使用的是 axios,我真的建议您使用 https://github.com/svrcekmichal/redux-axios-middleware 之类的东西

    然后你可以使用像这样的中间件

    const tokenMiddleware = store => next => action => {
      if (action.payload && action.payload.request && action.payload.request.secure) {
        const { auth: { isAuthenticated } } = store.getState()
        const secure = action.payload.request.secure
    
        if (!isAuthenticated && secure) {
          history.push({ pathname: 'login', query: { next: history.getCurrentLocation().pathname } })
          return Promise.reject(next({ type: 'LOGIN_ERROR', ...omit(action, 'payload') }))
        }
      }
    
      return next(action)
    }
    

    action.payload.request.secure 是我用来指示请求需要身份验证的自定义属性。

    在这种情况下,我还使用 react-router 中的历史记录进行重定向,但您可以处理它以调度另一个操作 (store.dispatch({ 不管 })) 并根据需要做出反应

    【讨论】:

    • 使用 axios 并使用 promise 中间件。
    猜你喜欢
    • 2017-03-28
    • 2018-10-19
    • 1970-01-01
    • 1970-01-01
    • 2021-07-05
    • 2010-09-06
    • 2019-05-20
    • 2016-07-02
    • 1970-01-01
    相关资源
    最近更新 更多