0

我的应用程序使用 react、react-router-dom 和stitch,它们正在访问 mongodb 并通过 google 处理身份验证。我能够验证和访问 ProtectedPage 组件,但是当我刷新时,isAuthed 将没有值,我将重定向到 /login。为什么状态没有更新,因此 isAuthed = true 以及如何确保在刷新时将我带到 /protected?

import React, {Component} from 'react';
import {
  Switch,
  Route,
  Link,
  Redirect,
  withRouter,
} from "react-router-dom";
import {Stitch, GoogleRedirectCredential} from 'mongodb-stitch-browser-sdk'

import './App.css';

class App extends Component{

  constructor(props) {
    super(props)

    this.state = {
      isAuthed: ''
    }
  }

  componentDidMount(){
    
    this.client = new Stitch.initializeDefaultAppClient("myAppId");

    if(this.client.auth.hasRedirectResult()){
      this.client.auth.handleRedirectResult();
    }
    
    this.setState({isAuthed: this.client.auth.isLoggedIn});
  }


  login = () => {
    const credential = new GoogleRedirectCredential() 
    this.user = this.client.auth.loginWithRedirect(credential);
  }

  logout = () => {
    this.client.auth.logout();
    this.setState({isAuthed: false});
  }

  showUser = () => {
    console.log(this.client.auth.isLoggedIn);
    console.log(this.client);
  }


  render() {
  return (
    <div className="App">
    <ul>
      <li>
        <Link to="/">Public Page</Link>
      </li>
      <li>
        <Link to="/login">Login</Link>
      </li>
      <li>
      <Link to="/protected">Protected Page</Link>
    </li>
    </ul>

    <Switch>
      <Route exact path="/">
        <PublicPage isAuthed={this.state.isAuthed}/>
      </Route>
      <Route path="/login" >
        <LoginPage login={this.login} isAuthed={this.state.isAuthed}/>
      </Route>
      <PrivateRoute path="/protected" isAuthed={this.state.isAuthed} >
        <ProtectedPage logout={this.logout} />
      </PrivateRoute>
    </Switch>

    </div>
  );
  }
}

export default withRouter(App);

function PublicPage() {
 
  return (
    <div><h3>Public</h3>
    </div>
    
  );

}

function ProtectedPage({logout}) {
 
  return (
      <div>
      <h3>You Are Logged In</h3>
        <button onClick={logout}>Logout</button>
      </div>
    );
}

function LoginPage({login}) {

  return (


    <div>
      <p>You must log in to view the page</p>
      <button onClick={login}>Log in</button>
    </div>
    
  );
}

function PrivateRoute({ children, isAuthed, client, ...rest}) {
  console.log(isAuthed);

  return (
    <Route
      {...rest}
      render={({ location }) =>
      isAuthed ? (
          children
        ) : (
          <Redirect
            to={{
              pathname: "/login",
              state: { from: location }
            }}
          />
        )
      }
    />
  );
}
4

2 回答 2

1

ComponentDidMount 仅在第一次调用 render 方法后才被调用。尝试将代码放入 componentWillMount 而不是 componentDidMount。

我建议将用户信息存储在浏览器本地存储中,而不是将 isAuthed 存储在状态中。

于 2020-06-23T23:54:42.067 回答
0

在 React 中状态是短暂的。每当您重新加载页面或执行重定向导致对新页面的 GET 请求时,状态将重置为您设置为默认值的任何内容,在 is 的情况this.state.isAuthed""

要解决此问题,您可以在用户登录时将isAuthed状态保存在 cookie 中localStorage或保存为 cookie。然后您可以拉入该值并在页面首次加载时使用componentDidMount或设置您的状态useEffect

只需确保在用户注销时清除您的localStorage或 cookie 值。isAuthed

于 2020-06-23T23:53:01.320 回答