防止来自redux操作的未经授权的ajax请求



我有一个这样定义的组件。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);
}

然后,在我的路由器配置中,我做了以下操作:

<Route path="brands" component={requireAuth(Brands)} />

如果本地存储中不存在验证令牌,则重定向到公共页面。然而,fetchBrands动作仍然被调用,这是触发一个ajax请求。由于缺乏验证令牌,服务器拒绝了它,但我甚至不希望进行调用。

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

我可以用if/else检查包装ajax请求,但考虑到我需要这样做的所有操作函数,这不是很DRY。我怎么能实现一些DRY来防止调用,如果auth在浏览器级别失败?

您应该为此编写一个中间件。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。调度({whatever}))并根据需要作出反应

相关内容

  • 没有找到相关文章

最新更新