No tienes acceso a esta clase

隆Contin煤a aprendiendo! 脷nete y comienza a potenciar tu carrera

Navigate y redirects: protegiendo rutas privadas

13/30
Recursos

Aportes 9

Preguntas 4

Ordenar por:

驴Quieres ver m谩s aportes, preguntas y respuestas de la comunidad?

o inicia sesi贸n.

Navigate y redirects: protegiendo rutas privadas

Como mencionamos anteriormente, si un usuario intenta acceder a una ruta privada por medio del historial o la barra de b煤squeda a煤n si esta no esta renderizada o no puede acceder lo que va a causar es que nuestra aplicaci贸n este en blanco, colapse y ya no se pueda interactuar hasta que recarguemos.

Para solucionar esto lo que haremos es protegerlas de verdad haciendo que si intentan acceder a una ruta parvada haga un redirect al home, a login o a profile dependiendo de la ruta donde intente acceder.

Para esto vamos primero a nuestro Profile.js:

// Importamos el componente navigate
import { useAuth } from '../../auth/auth';

function ProfilePage() {
  const auth = useAuth();

  /* Preguntamos si hay un usuario registrado, si no, redirigimos 
	a la persona */ 
  if (!auth.user) {
    /* Con este componente podemos hacer el redirect hacia donde la 
		l贸gica de nuestra aplicaci贸n lo requiera */ 
    return <Navigate to="/login" />
  }

  return (
    <>
      <h1>Perfil</h1>
      <h1>Welcome {auth.user.username}</h1>
    </>
  );
}

De esta manera si no nos hemos registrado e intentamos acceder a Profile por medio de la barra de b煤squeda nos redirigir谩 a nuestro login.

En caso de que necesitemos redireccionar varias veces a distintos sitios de nuestra aplicaci贸n veremos que hacer esto puede ser un poco repetitivo, debemos solucionar esto.

Vamos a auth.js y creemos una funci贸n que nos permita hacer esto m谩s sencillo.

import { Navigate } from 'react-router-dom';

...
/* En este compoinente podemos hacer la validaci贸n que es la misma 
que utilizamos con anterioridad */
function AuthRoute(props) {
  const auth = useAuth();

  if (!auth.user) {
    return <Navigate to="/login" />
  }

  return props.children
}

export {
	...
  AuthRoute,
}

Luego simplemente implementamos este componente en el ProfilePage.js:

import { AuthRoute, useAuth } from '../../auth/auth';

function ProfilePage() {
  const auth = useAuth();

  return (
    <AuthRoute>
      <h1>Perfil</h1>
      <h1>Welcome {auth.user.username}</h1>
    </AuthRoute>
  );
}

export { ProfilePage }

Si lo ejecutamos tendremos un error debido a que al renderizar el componente a煤n as铆 lo redireccionemos como auth.user.username no existe y esto nos dar谩 un error ya que en el componente lo estamos solicitando y esto nos genera un erro bloqueante al redireccionar a login.

Pero para que funcione esto en nuestro llamado desde App.js debemos importar a este componente ProfilePage dentro de un componente AuthRoute:

import { AuthProvider, useAuth, AuthRoute } from './Components/auth/auth'
...

function App() {
  return (
    <>
      <HashRouter>
        <AuthProvider>
          <Routes>
            ...
            <Route path='/profile' 
              element={
                <AuthRoute>
                  <ProfilePage /> {/* <-- */}
                </AuthRoute>
              } 
            />
          </Routes>
        </AuthProvider>

      </HashRouter>
    </>
  )
}

Y nuestro componente ProfilePage.js lo podemos dejar como estaba:

function ProfilePage() {
  const auth = useAuth();

  return (
    <>
      <h1>Perfil</h1>
      <h1>Welcome {auth.user.username}</h1>
    </>
  );
}

Ahora haremos lo mismo con el Logout en App.js:

<Route path='/logout' 
  element={
    <AuthRoute>
      <LogoutPage />
    </AuthRoute>
  } 
/>

Lo 煤nico que nos queda por hacer es que cuando estemos autenticados no podamos acceder a la p谩gina de Login, porque estamos protegiendo las rutas privadas de un usuario p煤blico pero no la ruta p煤blica de registro a un usuario privado. 隆Hagamos esto!

LoginPage.js

function LoginPage() {
	...	

  /* Como en este caso solo necesiamos hacer una validaci贸n lo 
  haremos directo en el componente preguntando si el usuario ya esta 
  registrado, si lo est谩 lo redirigiremos a la p谩gina de Profile 
  usando el Navigate */
  if(auth.user) {
    return <Navigate to="/profile" />
  }

  return (
		...
	)
}

Y hemos terminado de proteger nuestras rutas y tener una mejor l贸gica de aplicaci贸n.

Navigate y redirects: protegiendo rutas privadas

Es muy importante poder proteger rutas que a las que no queremos que el usuario sin autenticar tenga acceso.

Una forma para solucionar esto seria la utilizaci贸n del componente 鈥淣avigate鈥 (Con N may煤scula), por medio de un if, donde evaluamos si el usuario est谩 autenticado o no, vamos a indicarle a nuestro navegador que queremos redireccionar al usuario hacia 鈥/login鈥

const auth = useAuth()

  if(!auth.user){
    return <Navigate to="/login"/>
  }

Esto ya es una soluci贸n, pero existe otra forma m谩s simple de trabajar:

Dentro de nuestro archivo auth vamos a crear un componente, se podr铆a llamar 鈥淎utenticadorDeRutas鈥 o 鈥淎uthRoute鈥, y dentro de este vamos a incluir la l贸gica que aprendimos agregando que, en el caso de que si se pueda ver el contenido, se retorne el 鈥減rops.children鈥

function AuthRoute(props) {
  const auth = useAuth();

  if (!auth.user) {
    return <Navigate to="/login" />
  }

  return props.children
}

Por ultimo, tengo que decir que el componente AuthRouter es mejor llamarlo, justamente, en nuestro Router. De esta manera nos ahorramos problemas con valores que, asumimos, ya deber铆an existir en nuestros componentes si son renderizados.

<Route path='/profile' 
	element={
	  <AuthRoute>
	   <ProfilePage/>
	  </AuthRoute>
}/>

()= parentesis
{}=corchetes
[]=llaves

鈥榩or favor vete鈥 jajajajaj

Es la segunda vez que veo la clase en semanas diferentes y todavia me sorprendo de lo buena que es !!!

Felicitaciones!!

Que bueno, este error me toco en algunas paginas, ahora no recuerdo bien cuales, pero al estar logeado tenia la opcion de login

Nuestra principal estrategia en este caso fue el usar validaciones para permitir o no que una persona pueda acceder a diferentes paginas dependiendo de si est谩 logeada o no

No funciona porque a pesar de que si hace el redireccionamiento hacia login, igual sigue leyendo el resto del codigo del componente y cuando un usuario no se ha logeado, ese auth.user es null y en la linea 10 est谩 intentando leer una propiedad que es nula

incluso una render function me parecer铆a mas limpia para este caso