@Incold

Как правильно организовать приватный роутинг с использованием JWT?

Здравствуйте! Пытаюсь сделать роутинг для приложения. Сейчас при данной структуре, сталкиваюсь с проблемой, если вручную обновить страницу, то меня всегда редиректит на одну и туже страницу. Я понимаю почему это происходит, но пока не придумал как это решить:
App:
function App(props) {

    useEffect(() => props.checkUserToken() , []);  // вызывает action, который прослушивается сагой (ниже)
   
    return (
        <div className="d-flex align-items-center justify-content-center">
            <Switch>
                 <Route path='/authorization'
                       render={prop => !props.isLogin ? <Login {...prop}/> : <Redirect to="/main"/>}
                />

                <Route path='/main'
                       render={prop => props.isLogin ? <MainPage {...prop}/> : <Redirect to="/authorization"/>}
                />
                <Route
                    render={() => <Redirect to={props.isLogin ? '/main' : '/authorization'}/>}
                />
            </Switch>
            {
                props.loading && <Loading />
            }
        </div>
    )
}


MainPage:
...
<Switch>
      <Route exact path='/main/listings' component={ListingsList}/> //всегда редиректить на этот роут, если (ниже)
      <Route path='/main/listings/apartments_loft/:id' component={Listing}/>
      <Route exact path='/main/reservations' component={ReservationsList}/>
      <Route path='/main/reservations/reservation_info/:id' component={Reservation}/>
      <Route exact path='/main/settings' component={Settings}/>
      <Route path='/main/settings/add' component={AddSource} />
      <Route>
          <Redirect to='/main/listings' />
      </Route>
 </Switch>
...


Сага проверяющая токен:
function* checkJWT() {
    try {
        const token = yield localStorage.getItem('token');

        if (token) {
            yield Api.setAuthHeader(token); // создаёт header 'Authorization', который потом используется во всех api запросах
            yield put({type: TOKEN_EXIST}); // просто меняет isLogin на true
        }
        else {
            yield cancel();
        }

    }
    catch {
        yield cancel();
    }
}

export function* watchCheckJWT() {
    yield takeEvery(CHECK_TOKEN, checkJWT);
}


Если в App в роутах поменять render на component={...}, то всё работает (после обновления остаётся на том же роуте), я думаю (но не уверен) это из-за того, что теперь компонента не зависит от props.isLogin и не рендерится с нуля, но тогда нет защиты от неавторизованных пользователей.
Раньше я бы добавил componentWillMount и проблема была бы решена, но сейчас не рекомендуется использовать этот метод, т.к. он уйдёт в 17 версии.
Так как же правильно реализовать и защиту роутов, и правильное обновление страниц, что поменять, что добавить?
Заранее, спасибо, за любую помощь!
  • Вопрос задан
  • 156 просмотров
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы