Home > Enterprise >  How to redirect a user to any page they try to access after authentication (conditional redirect)?
How to redirect a user to any page they try to access after authentication (conditional redirect)?

Time:01-10

Using react router dom v 5, and with my little understanding of react I still don't know what I'm missing out. Some of the pages I have require a user to be authenticated before they can assess it. So I want a situation whereby then a user tries to assess any page that requires him to be logged in he is first of all redirected to login. After he has logged in I want him to be redirected to the page he was trying to access. In any page I want the user to be logged in I'm using the following in the useEffect:

useEffect(() => {

    if (!isAuthenticated) {
        history.push('/login')

    } else {
        dispatch(getCategory())
        }
    }
}, [dispatch])

With the code the user gets redirected if he is not authenticated, but after authentication he is redirected to the profile page instead of the page he was trying to access.

function LoginScreen({ isAuthenticated }) {
    const [email, setEmail] = useState('')
    const [password, setPassword] = useState('')

    const dispatch = useDispatch()
    const auth = useSelector(state => state.auth)
    const { error, loading } = auth
    
    const submitHandler = (e) => {
        e.preventDefault()
        dispatch(login(email, password))
    }

    if (isAuthenticated){
        return <Redirect to='/profile' />
    }

It is redirecting the user to the page I specified in the login component instead of redirecting the him to the page he was trying to access. How do I fix this?

CodePudding user response:

You should capture the current location that was being accessed before redirecting to the authentication page. Send this in route state to the login page.

const location = useLocation();

useEffect(() => {
  if (!isAuthenticated) {
    history.push({
      pathname: '/login',
      state: {
        from: location;
      }
    });
  } else {
    dispatch(getCategory())
  }
}, [dispatch]);

On the LoginScreen component access the passed route state to get the location to redirect back to.

function LoginScreen({ isAuthenticated }) {
  const dispatch = useDispatch();
  const { state: { from = "/" } = {} } = useLocation();

  const [email, setEmail] = useState('');
  const [password, setPassword] = useState('');

  const auth = useSelector(state => state.auth);
  const { error, loading } = auth;

  const submitHandler = (e) => {
    e.preventDefault();
    dispatch(login(email, password));
  }

  if (isAuthenticated){
    return <Redirect to={from} />;
  }

  ...

If this authentication check is something you do on more than say, one component, then you may want to invest in creating a custom route component to abstract this logic away from the UI components. See the RRDv5 auth workflow example.

  •  Tags:  
  • Related