2

Currently, I use the following PrivateRoute to determine if the user is logged in, and if so, the user is taken to the specified page, and if not, the user is taken to the login page. However, when I reload the page, it momentarily transitions to the login page and then to the root page, and I cannot display the /accounts or /notes page again.

This phenomenon also occurs when you type directly into the address bar.

If you know more about it, I would appreciate it if you could tell me why this kind of decrease is happening.

enter image description here

import React from 'react'
import { Route, Redirect } from 'react-router-dom'
import { connect } from 'react-redux'

const PrivateRoute = ({ component: Component, auth, ...rest }) => (
    <Route
        {...rest}
        render={props => {
            if (auth.isLoading) {
                return <h2>Loading...</h2>;
            } else if (auth.isAuthenticated) {
                return <Component {...props} />;
            } else {
                return <Redirect to='/login' />;
            }
        }}
    />
);

const mapStateToProps = state => ({
    auth: state.auth
})

export default connect(mapStateToProps)(PrivateRoute);

action

export const login = (username, password) => dispatch => {

    const config = {
        headers: {
            'Content-Type': 'application/json',
        }
    };

    const body = JSON.stringify({ username, password });

    axios
        .post(`${url}/api/auth/login`, body, config)
        .then((res) => {
            dispatch({
                type: LOGIN_SUCCESS,
                payload: res.data,
            });
        })
        .catch((err) => {
            dispatch(returnErrors(err.response.data, err.response.status));
            dispatch({
                type: LOGIN_FAIL,
            });
        });
};

space_pok
  • 179
  • 11
  • Do you have only one reducer? Should it be `auth: state.auth` or something like `auth: state.auth.auth`? – Ajeet Shah Mar 29 '21 at 05:28
  • Can you update the question with console log of the `auth` object at **PrivateRoute**. So it will provide more debug info. – Bishan Mar 29 '21 at 05:29
  • @Bishan What does "console log of the auth object at PrivateRoute" mean? – space_pok Mar 29 '21 at 05:31
  • @Ajeet Shah Only `auth: state.auth`. – space_pok Mar 29 '21 at 05:33
  • OK. Can you write `auth, ...rest }) => { console.log(auth); return – Ajeet Shah Mar 29 '21 at 05:34
  • @Ajeet Shah `{"token": "a39ddffee574dd1c5aed51edf790fc4","isAuthenticated": null,"isLoading": null,"user": null}` The output was. – space_pok Mar 29 '21 at 05:39
  • @space_pok According to the debug info, You don't have an authenticated user. That's why always redirects to the login page. Can you post the code stuff where you set data into `auth`. (need to see how you are handling the authentication in your app) – Bishan Mar 29 '21 at 05:56
  • @Bishan I've added the code for the action – space_pok Mar 29 '21 at 06:09

1 Answers1

2

The problem is that your auth state in redux will lost each time page reload so you can not identify authentication anymore. To prevent that your can save your state in localStorage or use redux-persist for it.

Vo Quoc Thang
  • 1,338
  • 1
  • 4
  • 5
  • Thank you for your answer. When you log in, set localStorage.setItem('auth', 1); and when you log out, set localStorage.setItem('auth', 0); and check if you are authenticated with localStorage.getItem("auth") == "1". Is this the right way to do it? – space_pok Mar 29 '21 at 06:31
  • Yup. remember use one consistent name "isAuth" or "auth" – Vo Quoc Thang Mar 29 '21 at 06:36
  • 2
    @space_pok Don't use `localStorage.setItem('auth', 1);` for auth check. To improve the security of you app, store encrypted auth data in local storage. then decrypt and check before perform auth related actions in your app. when logout, clear the auth data from local storage instead of setting value into 0. you can use `JWT` token for this and set expire time also. then the authenticated session will automatically get expired after given time and user need to re-login. – Bishan Mar 29 '21 at 06:58
  • @Bishan If I don't use localStorage.setItem('auth', 1);, how can I authorize it instead? – space_pok Mar 29 '21 at 13:17
  • @space_pok Your question is bit unclear. Do you want to achieve this without using the `localStorage` or using the `localStorage` with encrypted value instead of **('auth', 1)** ? – Bishan Mar 30 '21 at 03:34
  • @Bishan Which is more secure, using local storage without using local storage or using local storage with encrypted values? – space_pok Mar 30 '21 at 03:59
  • 1
    @space_pok Follow [Is it safe to store a JWT in localStorage with ReactJS?](https://stackoverflow.com/questions/44133536/is-it-safe-to-store-a-jwt-in-localstorage-with-reactjs) – Bishan Mar 30 '21 at 04:06