Writing for
Good
Insights
De la creación a la protección: Middleware Next.js y potencia del lado del servidor para páginas con funciones específicas
En Resumen
Next.js se ha convertido rápidamente en uno de los frameworks de React de referencia, en gran parte gracias a sus funciones fáciles de usar para los desarrolladores y a sus potentes capacidades integradas. Una de las características que definen a Next.js es su naturaleza híbrida, que permite tanto la renderización del lado del servidor como la generación de sitios estáticos, lo que lo convierte en una herramienta versátil en el arsenal de un desarrollador.
Sin embargo, a medida que las aplicaciones se amplían y crecen en complejidad, los desarrolladores se enfrentan a menudo a un reto crítico: asegurar las rutas y el contenido en función de los roles de los usuarios, especialmente en aplicaciones dinámicas con contenido específico para cada usuario.
Utilizando el middleware de Next.js
Antes de entrar en materia, vamos a entender el papel del middleware. En Next.js, el middleware permite ejecutar código del lado del servidor antes de que la aplicación gestione la solicitud. Esto presenta una oportunidad única para aplicar redireccionamientos basados en roles sin siquiera tocar el código principal de tu aplicación.
Por ejemplo, considere una aplicación web con diferentes paneles de control para administradores y empleados. Cuando los administradores inician sesión, deben ser redirigidos al panel de control del administrador, mientras que otros roles, como los empleados, ven su panel de control específico.
Estas son algunas de las mejores prácticas para configurar esto con middleware:

src/middleware.ts
import { withMiddlewareAuthRequired, getSession } from '@auth0/nextjs-auth0/edge'; import { NextResponse } from 'next/server'; import type { NextRequest } from 'next/server'; import { decodeToken } from './api/helpers/authorization.helper'; import { hasAdminRole } from './api/helpers/user-role.helper'; export default withMiddlewareAuthRequired(async (req: NextRequest) => { const res = NextResponse.next(); const session = await getSession(req, res); if (session && session.accessToken) { const permissions = decodeToken(session.accessToken).permissions; const isAdmin = hasAdminRole(permissions); if (isAdmin && req.nextUrl.pathname === '/') { return NextResponse.rewrite(new URL('/admin-dashboard', req.url)); } } return res; });
En el código anterior:
- Recuperamos la sesión de usuario.
- Decodificamos el token de acceso para obtener los permisos.
- Comprobamos si el usuario tiene el rol de administrador y le redirigimos al panel de administración.
Asegurando tus páginas en el lado del servidor
Aunque el middleware es potente para gestionar las redirecciones basadas en roles, la verdadera esencia de la seguridad reside en proteger el contenido en su origen: el servidor.
Si, por ejemplo, un usuario que no es administrador intenta entrar en la URL del panel de control de los administradores, el servidor le mostrará la página de error 404. Esto es muy importante porque
Esto es muy importante porque:
- Esto impedirá que el usuario acceda al panel de control de los administradores.
- El usuario ni siquiera sabrá qué ruta es la correcta para este panel de control porque será redirigido automáticamente a la página de error 404, lo que también podría ocurrir si escribe una URL que no existe. ¡Seguridad total!
Para el Admin-Dashboard:
Para evitar que los usuarios que no son administradores accedan directamente al panel de control escribiendo la URL, utilice apoyos del lado del servidor para validar el rol:
Del lado del servidor
src/server/admin-dashboard/admin-dashboard.tsx
import { GetServerSidePropsContext } from 'next'; import { getAccessToken } from '@auth0/nextjs-auth0'; import { decodeToken } from '../../api/helpers/authorization.helper'; import { hasAdminRole } from '../../api/helpers/user-role.helper'; async function adminDashboardPage({ req, res }: GetServerSidePropsContext) { const accessToken = (await getAccessToken(req, res)).accessToken; if (accessToken) { const permissions = decodeToken(accessToken).permissions; const isAdmin = hasAdminRole(permissions); if (!isAdmin) { return { notFound: true, }; } } else { return { notFound: true, }; } return { props: { token: accessToken, isHomePage: true } }; } export default adminDashboardPage;
Llamada a accesorios del lado del servidor en la página
src/pages/admin-dashboard/index.tsx
import Head from 'next/head'; import { useTranslation } from 'react-i18next'; export { default as getServerSideProps } from '../../server/admin-dashboard/admin-dashboard'; const AdminDashboard = () => { const { t } = useTranslation('common'); return ( <> <Head> <title>{t('title')}</title> </Head> {/* Rest of the page */} </> ); }; export default AdminDashboard;
En este código, si el usuario no tiene un rol de administrador o no está autenticado, recibirá una respuesta 404 Not Found, ocultando así el panel de administración.
Para el panel de control del empleado:
Mientras que el panel de administración requiere validación, el panel de empleados, en este ejemplo, se supone que es accesible a todos los usuarios autenticados:
Servidor
src/server/dashboard/dashboard.tsx
import { GetServerSidePropsContext } from 'next'; async function dashboardPage({ req, res }: GetServerSidePropsContext) { // No extra validation needed return { props: { isHomePage: true, }, }; } export default dashboardPage;
Llamada a accesorios del lado del servidor en Page
src/pages/dashboard/index.tsx
import Head from 'next/head'; import { useTranslation } from 'react-i18next'; export { default as getServerSideProps } from '../../server/dashboard/dashboard'; const Dashboard = () => { const { t } = useTranslation('common'); return ( <> <Head> <title>{t('title')}</title> </Head> {/* Rest of the page */} </> ); }; export default Dashboard;
Conclusión
Aprovechando la potencia del middleware Next.js y los accesorios del lado del servidor, los desarrolladores pueden crear experiencias seguras adaptadas a los distintos roles de usuario. Aunque esta guía se ha centrado en los cuadros de mando, estas técnicas pueden aplicarse a diversos escenarios para mejorar la experiencia y la seguridad del usuario. Prioriza siempre la seguridad y sé consciente de las implicaciones de la lógica que implementas.
Happy coding!