无法在Firebase + React Web应用程序中访问受保护的路由

时间:2018-07-01 21:01:44

标签: reactjs firebase react-router firebase-authentication

我正在使用React 16,Firebase 5(w / React Firebase UI)和Typescript 2在我的Web应用程序中设置身份验证和受保护的路由。我对这三个都比较陌生,所以我我一直在学习核心概念。我目前遇到的麻烦是我只是 获得了身份验证和路由保护设置,但是每当我尝试登录并重定向到/时,我都会跳回/signin

我的基本方法是将user设置为顶级状态属性,并将该状态传递给我的私有路由以进行身份​​验证。我监听firebase.auth().onAuthStateChanged,并根据传递给回调的值设置user状态。

我环顾四周,似乎我的方法朝着正确的方向发展(就Firebase身份验证模式和将状态作为道具传递给子组件而言),但是我注意到这似乎是最高级的组件(App呈现两次 :一次在user = null时呈现,第二次在user = {...firebase user properties }时呈现。我的解释只是将null的值传递给子组件,这会触发页面重定向回/signin,但我目前还不确定。

这是我的代码:

index.tsx:

class App extends React.Component<any, any> {
  constructor(props: any) {
    super(props);

    this.state = {
      user: null
    };
  }

  componentDidMount() {
    let self = this;
    firebaseApp.auth().onAuthStateChanged(function(user: Object) {
      if (user) {
        self.setState({ user: user });
      }
    });
  }

  render() {
    return <Router>
            <Switch>
              {/* private routes */}
              <PrivateLayout exact path="/" user={this.state.user} component={Dashboard} />
              <PrivateLayout path="/listings" user={this.state.user} component={Listings} />
              <PrivateLayout path="/transact" user={this.state.user} component={Transact} />
              <PrivateLayout path="/bids" user={this.state.user} component={Bids} />
              <PrivateLayout path="/account" user={this.state.user} component={Account} />
              <PrivateLayout path="/support" user={this.state.user} component={Support} />

              {/* public routes */}
              <PublicLayout path="/signin" component={Authenticate} />
              <PublicLayout component={NoMatch} />
            </ Switch>
           </Router>;
  }
}


ReactDom.render(<App /> , document.getElementById('app'));

PrivateLayout.tsx:

declare interface PrivateRouteProps extends RouteProps {
  user: Object;
}

class Private extends React.Component<PrivateRouteProps, any> {

  render() {
    if (this.props.user) {
      return <Route {...this.props} render={(matchProps: RouteProps) => {
        return <div className="ag-layout-private">
            <Header />
            <Navbar />
            <div className="ag-content">
              {/* render final component here */}
            </div>
          </div>
        }
      }/>;
    }

    return <Redirect to={{pathname: '/signin'}}/>;
  }
} 

export default Private;

Authenticate.tsx(/signin组件):

class Authenticate extends React.Component<any, any> {
  uiConfig = {
    signInSuccessUrl: '/',
    signInOptions: [
      firebase.auth.EmailAuthProvider.PROVIDER_ID,
      firebase.auth.GoogleAuthProvider.PROVIDER_ID
    ]
  }

  render() {
    return  <div className="ag-signin">
              <h3>Sign In</h3>
              <FirebaseAuth uiConfig={this.uiConfig} firebaseAuth={firebaseApp.auth()} />
            </div>; 
  }
}

export default Authenticate;

这时我很迷路。您可以提供的任何建议将不胜感激(包括此设置是否是我尝试实现的身份验证流程的最佳方法)。

0 个答案:

没有答案