Есть ли способ для моего приложения react отображать при входе в систему(аутентификация aws), чтобы просматривать защищенные маршруты без обновления страницы вручную

#javascript #reactjs #amazon-web-services #aws-amplify

Вопрос:

У меня есть веб-приложение react, в котором я использую аутентификацию aws amplify для управления входом и выходом.

Я использую следующие два класса для модального pop, который обрабатывает вход в систему:

 export class Logins2 extends Component {
  handleChange = (e) => {
    const target = e.target;
    let name = target.name;
    let value = target.value;

    this.setState({
      [name]: value,
    });
  };
  handleSubmitAssign = (e) => {
    //e.preventDefault();

    console.log(e);

  };
  handleAuthStateChange(state) {
    console.log(state)
   }
  
  render() {

    return (
      <Modal show={this.props.isOpen} onHide={this.props.closeModal} centered>
        <Modal.Header closeButton>
          <Modal.Title>Login</Modal.Title>
        </Modal.Header>
        <Modal.Body>
          <Authenticator hideDefault={true} onStateChange={this.handleAuthStateChange}>
            <SignIn/>
            <Greetings
              inGreeting={(username) => "Hello "   username}
              outGreeting="Please sign in"
            />
          </Authenticator>
        </Modal.Body>
        <Modal.Footer>
          
        </Modal.Footer>
      </Modal>
    );
  }
}
 
 class SignIn extends Component {
  constructor(props) {
    super(props);
    this.state = {
      LogisOpen: false,
    };

  }

  openLog = () => this.setState({ LogisOpen: true });
  closeLog = () => this.setState({ LogisOpen: false });
 

  handleInputChange(event) {
    const target = event.target;
    let name = target.name;
    let value = target.value;

    this.setState({
      [name]: value,
    });
  }

  handleSubmit = (event) => {
    event.preventDefault();
    
  };

  render() {
    return (
      <div>
        <Button onClick={this.openLog} position= "center">Login/SignOut</Button>
        
        {this.state.LogisOpen ? (
          <Logins2
            closeModal={this.closeLog} 
            isOpen={this.state.LogisOpen} 
          />
        ) : null}
        </div>
        );
  }
}
 

I call sign in my App.jsx which switches between protected and unprotected routes depending on authentication.

 class App extends Component {
  constructor(props) {
    super(props);
    this.state = {
      authStatus: false,
      loading: false,
    };
  }
  componentDidMount() {
    Auth.currentAuthenticatedUser()
      .then((user) => {
        this.setState({ loading: false, authStatus: true });
        console.log(user)
      })
      .catch(() => {
        this.setState({ loading: false });
        //this.props.history.push('/LogIn');
      });
  }
  render() {
    Auth.currentAuthenticatedUser({
      bypassCache: true, // Optional, By default is false. If set to true, this call will send a request to Cognito to get the latest user data
    })
      .then((user) => console.log(user))
      .catch((err) => console.log(err));
    if (this.state.authStatus === true) {
      return (
        <div className="app">
          <h1>O.D.U. AWSMTURK DEMO</h1>
          <BrowserRouter forceRefresh={false}>
            <ProtectedRoute />
          </BrowserRouter>
        </div>
      );
    } else {
      return (
        <div className="app">
          <h1>O.D.U. AWSMTURK DEMO</h1>
          <BrowserRouter forceRefresh={false}>
            <Main />
          </BrowserRouter>
        </div>
      );
    }
  }
}
 

Моя проблема заключается в том, что при входе в систему мое приложение не отображает изменения. Поэтому, если я не вошел в систему, а затем вошел, мне придется вручную обновить страницу, чтобы просмотреть защищенные маршруты.

Поэтому мне было интересно, как это исправить, чтобы при входе или выходе страница отображалась в соответствии с текущим состоянием.

Комментарии:

1. Добавьте некоторое «аутентифицированное» состояние в App компонент и передайте обработчик SignIn таким образом, чтобы при изменении состояния аутентификации вы могли обновить состояние App и запустить повторную отправку. Или, если у Auth объекта есть прослушиватель, на который вы можете подписаться, вы можете использовать его.

Ответ №1:

Для всех, у кого также есть эта проблема, чтобы исправить ее, я использовал прослушиватель aws amplify auth hub в своем компоненте приложения. Мой конструктор компонентов, componentDidMount и прослушиватель выглядят следующим образом:

 constructor(props) {
    super(props);
    this.state = {
      authStatus: false,
      loading: false,
    };
    this.listener = this.listener.bind(this);
  }
 
 componentDidMount() {
    Hub.listen('auth', this.listener);
    Auth.currentAuthenticatedUser()
      .then((user) => {
        this.setState({ loading: false, authStatus: true });
      })
      .catch(() => {
        this.setState({ loading: false });
        //this.props.history.push('/LogIn');
      });
  }
 
   listener = (data) => {
    switch (data.payload.event) {
        case 'signIn':
            this.setState({authStatus: true });
            break;
        case 'signOut':
            this.setState({ authStatus: false });
            break;
        default:
          break;
    }
}
 

Вот
документация aws