I
I
Incold2020-07-22 16:21:04
React
Incold, 2020-07-22 16:21:04

How to properly organize private routing using JWT?

Hello! I'm trying to make a routing for the application. Now, with this structure, I encounter a problem, if I manually refresh the page, then I always redirect to the same page. I understand why this is happening, but have not yet figured out how to solve it:
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>
...


Token verification saga:
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);
}


If in the App in the routes we change render to component={...}, then everything works (after the update it remains on the same route), I think (but not sure) this is due to the fact that now the component does not depend on props. isLogin and is not rendered from scratch, but then there is no protection against unauthorized users.
In the past, I would have added a componentWillMount and the problem would have been solved, but it is not recommended to use this method now, because it will go in version 17.
So how to implement both the protection of routes and the correct updating of pages, what to change, what to add?
Thanks in advance for any help!

Answer the question

In order to leave comments, you need to log in

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question