【问题标题】:React - Redirect user is not authenticatedReact - 重定向用户未经过身份验证
【发布时间】:2020-02-22 13:57:54
【问题描述】:

我正在使用 Firestore,并且可以访问将通知我用户是否已通过身份验证的状态。我将这些条件映射到道具,如果未通过身份验证,我将使用react-router-dom 的重定向将用户导航到登录页面。

但是,当我在控制台记录身份验证状态时,我看到最初它会在加载此信息时显示为 false,然后切换为 true。但是,当它看到用户通过身份验证时,我已经重定向了他们。

我应该如何根据他们在 react 中的身份验证来重定向用户?

export class PrimaryNavBar extends Component {
  
  render(){
    const { auth, location } = this.props;
    const authenticated = auth.isLoaded && !auth.isEmpty;

    return (
      <React.Fragment>
      {!authenticated ? <Redirect to="/"/> : null}
      <Navbar bg="primary" variant="dark">
        <Container>
          <Link to="/">
    ....

我在这里查看了其他答案,但它们并没有真正帮助重定向,如果没有经过身份验证,只会呈现空值。

更新

我将代码重组为重定向将发生在 app.js 文件中

新的问题是,每当我用户更改路由时,它都会重新检查身份验证,这最初是错误的,最终会回到登录屏幕。

class App extends Component {
  state = {
    isAuthenticated: this.props.isAuthenticated
  }

  render() {
    const logoutHandler = () => {
      this.props.firebase.logout();
    };
    const authenticated = this.props.auth.isLoaded && !this.props.auth.isEmpty;
    return (
      <Aux>
        {!authenticated ? <Redirect to="/" /> : null}
        <Route path="/" exact component={Login} />
        <Route path='/(.+)' render={() => (
          <React.Fragment>
            <PrimaryNavBar logout={logoutHandler} />
            <Switch>
              <Route path="/dashboard" exact component={Dashboard} />
              <Route path="/auctions" component={Auctions} />
              <Route path="/auctions/:id" component={AuctionItem} />
              <Route path="/auctions/create-auction" component={CreateAuction} />
              <Route path="/bidders/create-bidder" component={CreateBidder} />
              <Route path="/bidders/:id" component={Bidder} />
              <Route path="/bidders" component={Bidders} />
            </Switch>
          </React.Fragment>
        )} />
        <ReduxToastr position="bottom-right" />
      </Aux>
    );
  }

}
const mapStateToProps = state => {
  return {
    isAuthenticated: state.firebase.auth.uid,
    auth: state.firebase.auth
  };
};

const mapDisptachToProps = dispatch => {
  return {};
};


export default withRouter(withFirebase(
  connect(
    mapStateToProps,
    mapDisptachToProps
  )(App)
));

【问题讨论】:

  • 如果你在 Redux 存储中存储 auth 状态,为什么你说 auth 状态一开始会是 false 呢?如果之前已经设置过?根据我所能收集到的你所做的,我会将身份验证检查放在 ComponentDidMount 或 useEffect 块中,并异步运行它对数据的身份验证获取。然后你就知道在进行任何其他检查之前你已经有了一个固定的状态。
  • 另外我注意到您正在使用 Redux,那么您如何调度操作以获取身份验证数据?请记住,React-Redux 是同步的,您需要使用一些中间件来处理对服务器和 api 的异步调用。像 Redux-thunk 或 Sagas 之类的东西
  • firebase 在后台执行所有这些魔术,以查看用户是否已经登录。在生命周期中,由于需要时间加载,身份验证将解析为 false。我进行调度以从登录屏幕登录用户。我大部分工作都在工作,但现在我不知道如何将用户引导到应用程序,如果他们已登录。如果每条路线都看到他们经过身份验证,然后将他们重定向回仪表板(登陆页面),现在会发生什么>
  • 我自己使用 Firebase。我要说的是,当您请求身份验证令牌然后获取 uid 时,这必须异步完成。您的代码不会等待请求进来,但您可以这样做。该请求将返回一个承诺,然后您可以使用 .then() 获取 uid 并更新您的本地状态。只有完成后,您才想继续执行代码并渲染后续组件。或者,如果你想更新 Redux 状态,你必须使用中间件进行异步操作

标签: reactjs firebase react-router


【解决方案1】:

您可能应该等到auth.isLoaded 为真?如果是这样,你可以这样做

const { auth, location } = this.props;
if (!auth.isLoaded) return null

这将阻止您的导航组件呈现,直到加载身份验证信息。不过,您可能需要考虑在父组件级别实现此检查(和重定向)。

【讨论】:

  • 这确实有助于确保用户在路由更改期间没有被重定向回登录屏幕,但现在我无法在登录后将经过身份验证的用户引导到应用程序。
  • 我刚刚进入登录组件并在用户登录时进行了重定向。如果这一切都是从 app.js 完成的,但它可以工作,所以继续前进。
猜你喜欢
  • 2019-04-25
  • 1970-01-01
  • 2016-08-08
  • 2015-04-20
  • 2015-09-28
  • 2020-11-15
  • 2016-01-17
  • 2013-10-25
  • 1970-01-01
相关资源
最近更新 更多