Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
October 14, 2022 01:32 pm GMT

Proteccin de rutas con React Router Dom.

En esta ocasin vamos a usar la libreara de react router dom para poder crear rutas protegidas en nuestra aplicacin de React JS.

Cualquier tipo de feedback es bienvenido, gracias y espero disfrutes el articulo.

Nota: Es necesario que cuentes con nociones de React Router Dom.

Tabla de contenido

Tecnologas a utilizar.

Creando el proyecto.

Primeros pasos.

Creando las paginas.

Integrando React Router.

Agregando proteccin de rutas.

Conclusin.

Cdigo fuente.

Tecnologas a utilizar.

  • React JS (version 18)
  • Vite JS
  • TypeScript
  • React Router Dom (version 6)
  • CSS vanilla (Los estilos los encuentras en el repositorio al final de este post)

Creando el proyecto.

Al proyecto le colocaremos el nombre de: protected-routes (opcional, tu le puedes poner el nombre que gustes).

npm init vite@latest

Creamos el proyecto con Vite JS y seleccionamos React con TypeScript.

Luego ejecutamos el siguiente comando para navegar al directorio que se acaba de crear.

cd protected-routes

Luego instalamos las dependencias.

npm install

Despus abrimos el proyecto en un editor de cdigo (en mi caso VS code).

code .

Primeros pasos.

Vamos al archivo src/App.tsx y borramos todo el contenido para crear un nuevo componente. Que por el momento solo renderizar un "hola mundo"

const App = () => {  return (    <>        <div>Hello world</div>    </>  )}export default App

Lo que sigue es crear un Layout, esto solo es con propsito de esttica para la app, no es obligatorio.

Nota: Cada vez que creamos una nueva carpeta, tambin crearemos un archivo index.ts para agrupar y exportar todas las funciones y componentes de otros archivos que estn dentro de la misma carpeta, y que dichas funciones puedan ser importadas a traves de una sola referencia a esto se le conoce como archivo barril.

Creamos la carpeta src/components y dentro creamos el archivo Layout.tsx para agregar:

interface Props { children: JSX.Element | JSX.Element[] }export const Layout = ({ children }: Props) => {    return (        <div>            <h1>Protected Routes with <br /> <span>React Router</span></h1>            {children}            <div className="logo">                <img src="https://cdn.svgporn.com/logos/react-router.svg" alt="react-router" />            </div>        </div>    )}

Luego lo importamos en el archivo src/App.tsx

import { Layout } from "./components"import { AppRouter } from "./routes"const App = () => {  return (    <Layout>    </Layout>  )}export default App

Debera lucir as

first

Creando las paginas.

Creamos la carpeta src/pages y dentro creamos dos archivos:

  • HomePage.tsx, que actuara como la pagina que queremos que sea privada, o sea que solo usuarios con alguna autenticacin puedan visualizar dicha pagina, incluso si el usuario sabe la URL de la pagina, no debe de poder verla.
export const HomePage = () => {    return (        <div className="page">HomePage</div>    )}
  • LoginPage.txs, que actuara como la pagina publica que cualquiera que no tenga autenticacin pueda ver, pero si el usuario ya tiene una autenticacin entonces esta pagina no debe ser visible ni conociendo la URL.
export const LoginPage = () => {    return (        <div className="page">LoginPage</div>    )}

Aun no vamos a importar en ningn lado estas dos paginas.

Cabe mencionar que no se realizara ningn mtodo de autenticacin o algo parecido.

Agregando React Router.

Primero tenemos que instalar react router dom:

npm install react-router-dom

Despus creamos una carpeta src/routes y creamos el archivo AppRouter.tsx.

Este archivo sera el root de nuestro router, de aqu se desencadenaran las dems rutas.

Creamos un componente funcional.

export const AppRouter = () => {    return ()}

Tenemos que importar algunos componentes que nos ofrece react-router-dom.

  • BrowserRouter, este componente tiene que envolver toda nuestra aplicacin ya que es un proveedor. Una opcin tambin es colocarlo en el archivo src/main.tsx, pero en mi caso me gustara ponerlo en este archivo AppRouter.tsx y como este es el root de las rutas entonces esto es lo que vamos a importar en src/App.tsx

  • Routes, este componente debe estar dentro del BrowserRouter, y es el contenedor de las rutas que maneja nuestra aplicacin, y cada vez que la ubicacin cambia, este componente busca entre todas sus rutas hijas, para encontrar una ruta que coincida con la ubicacin y poder renderizar el elemento que expone esa ruta hija.

  • Route, este componente es donde se definir la ruta (mediante la prop path) y el elemento a renderizar (mediante la prop element pasando un elemento JSX).

    • Cuando colocamos un '*' en la prop path, significa que en caso de que ninguna ruta anterior conicidad con la ubicacin, entonces podemos renderizar una pagina 404, pero en este caso, se manda al usuario a otra ubicacin.
  • Navigate, este componente sirve para cambiar la ubicacin actual cuando se renderiza.

    • to, es la prop para colocar el path hacia donde quieres ir en tu aplicacin.
    • replace es la prop para quitar del historial de navegacin la actual ruta, y colocar la nueva ruta a la que te diriges. O sea que cuando quieras volver atrs, esa ya no estar la anterior pagina.
  import { BrowserRouter, Routes, Route, Navigate } from "react-router-dom"export const AppRouter = () => {    return (        <BrowserRouter>            <Routes>                <Route path='/' element={<HomePage />} />                <Route path='login' element={<LoginPage />} />                <Route path='*' element={<Navigate to='/login' replace />} />            </Routes>        </BrowserRouter>    )}

Listo, aqu tenemos
Y ahora necesitamos hacer cambios en el AppRouter.tsxor el momento nuestro root router.

Ahora vamos a colocarlo en src/App.tsx

import { Layout } from "./components"import { AppRouter } from "./routes"const App = () => {  return (    <Layout>      <AppRouter />    </Layout>  )}export default App

Notaras que va a renderizar el HomePage.tsx, esto es porque cuando entramos a nuestra app, por defecto el path / y coincide con la ruta que renderiza el HomePage.tsx

home

Y si en la barra de direccin colocas /login, entonces te muestra el LoginPage.tsx.

Pero si colocas otra cosa que no sea un simple / o /login, entonces por defecto seria * y renderiza el componente Navigate que te manda al /login.

Agregando proteccin de rutas.

Por defecto, puedes visualizar el HomePage.tsx pero no debera ser posible, ya que no tienes una "autenticacin". Asi que vamos a convertir esta ruta en una ruta privada.

Vamos a crear un nuevo archivo en src/routes nombrado PrivateRoutes.tsx

Y dentro vamos a crear una nuevo conjunto de rutas, que sern nuestras rutas privadas.

Para anidar rutas necesitamos tanto el contenedor de rutas que es el componente Routes y las rutas como tal que son el componente Route

Aqu irn todas las rutas que queremos que sean privadas. Solamente movemos la ruta que renderiza el HomePage a este componente.

Y ademas agregaremos una nueva ruta para mandar al usuario en caso de que el usuario ingrese una ruta que no exista en .nuestra app.

Con el comodn '*' en la prop

import { Navigate, Route, Routes } from 'react-router-dom';import { HomePage } from '../pages';export const PrivateRoutes = () => {    return (        <Routes>            <Route path='/' element={<HomePage />} />            <Route path='*' element={<Navigate to='/' replace />} />        </Routes>    );};

Y ahora necesitamos hacer cambios en el AppRouter.tsx

Vamos a simular la autenticacin con una simple variable (aunque en una app real lo mas probable es que venga de un API), lo importante es que tengas acceso a algn valor que te indique si el usuario esta autenticado o no y puedas usar dicho valor en el AppRouter.tsx:

type Status = 'checking' | 'authenticated' | 'no-authenticated'let status: Status = 'no-authenticated'

En el caso de la opcin checking es cuando inicia la app y no sabes si el usuario esta autenticado o no. En ese caso puedes renderizar un loading.

if (status === 'checking') return <div className="loading">Checking credentials...</div>

loading

Y ahora haremos una condicin dentro del contenedor de Rutas, donde si el usuario esta autenticado entonces djalo ver las rutas privadas y no muestres el login que en este punto sera innecesario ya que el usuario ya esta autenticado.

De lo contrario, no renderize el componente de rutas privadas y muestra el LoginPage

Y al final, despus de la condicin, seguimos manteniendo la ruta con el comodn [*] ya que si el usuario ingresa una ruta que no exista entonces, hay que mandarlo a alguna parte que si existe de nuestra app.

Nota que en la ruta donde usamos [] el path de la prop **to* es /login y no es simplemente login. Ya que si colocamos solo la palabra login entonces mantendr la URL como esta y solo le adicionara /login, lo cual no queremos.

Por ejemplo, si estamos en http://localhost:5173/about y queremos mandar al usuario a login, y en el componente Navigate en la prop to solo colocamos login sin el / al inicio entonces la URL resultante seria http://localhost:5173/about/login pero nosotros queremos apuntar al root de nuestras rutas y es por eso que debemos colocar el smbolo / al inicio, para que te envi a la URL http://localhost:5173/login

import { BrowserRouter, Routes, Route, Navigate } from "react-router-dom"import { PrivateRoutes } from "./"import { LoginPage } from '../pages';type Status = 'checking' | 'authenticated' | 'no-authenticated'let status: Status = 'no-authenticated'export const AppRouter = () => {    if (status === 'checking') return <div className="loading">Checking credentials...</div>    return (        <BrowserRouter>            <Routes>                {                    status === 'authenticated'                        ? <Route path="/*" element={<PrivateRoutes />} />                        : <Route path="login" element={<LoginPage />} />                }                <Route path='*' element={<Navigate to='/login' replace />} />            </Routes>        </BrowserRouter>    )}

Tambin nota que el path de las rutas privadas es '/*' significa que cualquier ruta que coincida con el / entonces entra al componente PrivateRoutes.

Un ejemplo seria: tienes la ruta about/* y alguien coloca el en buscador about/me entonces eso seria permitido y accedera al elemento que renderiza esa ruta. Si quitaras el comodn [*] entonces la ruta about/me ya NO sera permitido.

Hasta aqu ya tendramos nuestras rutas privadas, y una sola ruta "publica" pero que tal si tenemos mas rutas publicas como la de crear usuario, entonces debemos crear un nuevo componente llamado PublicRoutes.tsx

Y agregar las rutas que queremos que sean "publicas" o sea disponibles cuando el usuario no este autenticado.

import { Navigate, Route, Routes } from 'react-router-dom';import { LoginPage } from '../pages';export const PublicRoutes = () => {    return (        <Routes>            <Route path='login' element={<LoginPage />} />            <Route path='*' element={<Navigate to='/login' replace />} />        </Routes>    );};

Y asi quedara nuestra AppRouter.tsx.

import { BrowserRouter, Routes, Route, Navigate } from "react-router-dom"import { PrivateRoutes, PublicRoutes } from "./"type Status = 'checking' | 'authenticated' | 'no-authenticated'let status: Status = 'authenticated'export const AppRouter = () => {    if (status === 'checking') return <div className="loading">Checking credentials...</div>    return (        <BrowserRouter>            <Routes>                {                    status === 'authenticated'                        ? <Route path="/*" element={<PrivateRoutes />} />                        : <Route path="/*" element={<PublicRoutes />} />                }                <Route path='*' element={<Navigate to='/login' replace />} />            </Routes>        </BrowserRouter>    )}

Notaras que ambas rutas tienen el mismo path, pero no sera un problema ya que su existencia es condicional, o solo existir una ruta siempre.

Por cierto, si necesitas que alguna ruta sea accedida con o sin autenticacin entonces colcala en el AppRouter.tsx despus de la condicin.

Y asi tendramos rutas tanto publicas y privadas.

Conclusin.

Las rutas privadas son de mucha relevancia hoy en dia en las aplicaciones. Y con ayuda de React Router Dom nos hace mucho mas fcil la implementacin de dicho proceso.

Otra idea que te puedo dar es que en las rutas privadas puedes anidar otras rutas para dividirlos por rol por ejemplo, si un usuario tiene el rol de 'user' no podr ver la pagina de Admin, pero si tiene el rol de 'admin' entonces si podr ver dicha pagina.

Espero que te haya gustado esta publicacin y que te haya ayudada a entender ms sobre como usar React Router Dom para implementar la proteccin de rutas.

Esta forma de hacer rutas privadas, no es la nica, si es que conoces alguna otra forma distinta o mejor de realizar esta funcionalidad con gusto puedes comentarla .

Te invito a que revises mi portafolio en caso de que ests interesado en contactarme para algn proyecto! Franklin Martinez Lucas

No olvides seguirme tambin en twitter: @Frankomtz361

Cdigo fuente.

GitHub logo Franklin361 / protected-routes

Create protected routes with React and React Router Dom

Proteccin de rutas con React Router Dom.

This time, we are going to create protected routes with React Router Dom!

demo

Features

  1. Protected Routes.
  2. Show Public Routes.
  3. Redirecting.

Technologies

  • React JS (v 18)
  • Vite JS
  • TypeScript
  • React Router Dom
  • CSS vanilla

Installation

  1. Clone the repository (you need to have Git installed).
    git clone https://github.com/Franklin361/protected-routes
  1. Install dependencies of the project.
    npm install
  1. Run the project.
    npm run dev

Article links

Here's the link to the tutorial in case you'd like to take a look at it! eyes


Original Link: https://dev.to/franklin030601/proteccion-de-rutas-con-react-router-dom-144j

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To