Как выполнить аутентификацию дескриптора в маршрутизаторе React?

#reactjs #react-router

#reactjs #react-маршрутизатор

Вопрос:

Я использую следующий код, чтобы проверить, аутентифицирован ли пользователь в данный момент для доступа к определенному маршруту. Но это не работает, поскольку всегда приводит к тому, что авторизация не выполняется. Я проверил метод authenticate(), и он сработал, вернув true . Не могли бы вы взглянуть на это и выяснить, почему это не удалось? Заранее спасибо.

 const auth = {
    authenticate() {
      fetch('/isAuth')
        .then(response => response.json())
        .then(json => {
          if (json.code === 200) {
            return true;
          } else {
            return false;
          }
      })
    }
  }

  const PrivateRoute = ({ component: Component, ...rest }) => (
    <Route {...rest} render={(props) => (
      auth.authenticate() === true
        ? <Component {...props} />
        : <Route path="/notAuthed" exact component={notAuthed} />
    )} />
  )

  return (
    <Switch>
      <Route path="/auth" component={Auth} />

      <PrivateRoute path='/' component={Index} />

    </Switch>
  );
  

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

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

Ответ №1:

Вы можете использовать переменную состояния для сохранения результата аутентификации, поскольку fetch асинхронный auth.authenticate не вернет желаемое значение. Вы можете выполнить повторную визуализацию после завершения выборки.

 const [isAuthenticate, setIsAuthenticated] = useState(null);
const auth = {
    authenticate() {
      fetch('/isAuth')
        .then(response => response.json())
        .then(json => {
          if (json.code === 200) {
            setIsAuthenticated(true)
          } else {
            setIsAuthenticated(false)
          }
      })
    }
  }

  

Затем вы можете инициализировать маршруты следующим образом:-

 <Route {...rest} render={(props) => (
      isAuthenticated === null?<LoadingSpinner/>:isAuthenticated
        ? <Component {...props} />
        : <Route path="/notAuthed" exact component={notAuthed} />
    )} />
  

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

1. Здравствуйте, большое спасибо за вашу помощь! Это работает, когда я пытаюсь использовать isAuthenticated === null?auth.authenticate():isAuthenticated . Для повторного рендеринга, как я могу узнать, когда он будет повторно отображен и каков процесс повторного рендеринга?

2. Всякий раз, когда вы изменяете переменную состояния в react с помощью setState (вот она setIsAuthenticated ), компонент повторно отображается.

3. Понял. Большое вам спасибо за столь полезное объяснение.

Ответ №2:

 authenticate() {
  fetch('/isAuth')
    .then(response => response.json())
    .then(json => {
      if (json.code === 200) {
        return true;
      } else {
        return false;
      }
  })
}
  

Описанный выше метод извлекает конечную точку isAuth вашего приложения и проверяет, равен ли ответ 200 == OK.

Если isAuth не найден или вообще возвращает другой код ответа HTTP, метод вернет false и, таким образом, сигнализирует о том, что пользователь не аутентифицирован.

Вам нужно будет указать fetch на существующий маршрут и проверить аутентификацию пользователя.

И поскольку метод использует выборку (**), вам также придется ожидать ответа. Подробнее об этом: https://dev.to/johnpaulada/synchronous-fetch-with-asyncawait