Autenticación

La autenticación verifica la identidad de un usuario, mientras que la autorización controla lo que un usuario puede acceder. Next.js soporta múltiples patrones de autenticación, cada uno diseñado para diferentes casos de uso. Esta página revisará cada caso para que puedas elegir según tus necesidades.

Patrones de Autenticación

El primer paso para identificar qué patrón de autenticación necesitas es entender la estrategia de obtención de datos que deseas. Luego podemos determinar qué proveedores de autenticación soportan esta estrategia. Hay dos patrones principales:

  • Usar generación estática para renderizar un estado de carga en el servidor, seguido de obtener los datos del usuario en el cliente.
  • Obtener datos del usuario en el servidor para eliminar destellos de contenido no autenticado.

Autenticación en Páginas Generadas Estáticamente

Next.js determina automáticamente que una página es estática si no tiene requisitos de datos bloqueantes. Esto significa la ausencia de getServerSideProps y getInitialProps en la página. En su lugar, tu página puede renderizar un estado de carga desde el servidor, seguido de obtener al usuario en el cliente.

Una ventaja de este patrón es que permite servir páginas desde una CDN global y precargarlas usando next/link. En la práctica, esto resulta en un TTI (Tiempo hasta Interactivo) más rápido.

Veamos un ejemplo para una página de perfil. Esto renderizará inicialmente un esqueleto de carga. Una vez que la solicitud del usuario termine, mostrará el nombre del usuario:

pages/profile.js
import useUser from '../lib/useUser'
import Layout from '../components/Layout'

const Profile = () => {
  // Obtiene el usuario en el cliente
  const { user } = useUser({ redirectTo: '/login' })

  // Renderiza estado de carga desde el servidor
  if (!user || user.isLoggedIn === false) {
    return <Layout>Cargando...</Layout>
  }

  // Cuando la solicitud del usuario termine, muestra al usuario
  return (
    <Layout>
      <h1>Tu Perfil</h1>
      <pre>{JSON.stringify(user, null, 2)}</pre>
    </Layout>
  )
}

export default Profile

Puedes ver este ejemplo en acción. Revisa el ejemplo with-iron-session para ver cómo funciona.

Autenticación en Páginas Renderizadas en el Servidor

Si exportas una función async llamada getServerSideProps desde una página, Next.js pre-renderizará esta página en cada solicitud usando los datos devueltos por getServerSideProps.

export async function getServerSideProps(context) {
  return {
    props: {}, // Se pasará al componente de página como props
  }
}

Transformemos el ejemplo del perfil para usar renderizado en el servidor. Si hay una sesión, devuelve user como prop al componente Profile en la página. Nota que no hay un esqueleto de carga en este ejemplo.

pages/profile.js
import withSession from '../lib/session'
import Layout from '../components/Layout'

export const getServerSideProps = withSession(async function ({ req, res }) {
  const { user } = req.session

  if (!user) {
    return {
      redirect: {
        destination: '/login',
        permanent: false,
      },
    }
  }

  return {
    props: { user },
  }
})

const Profile = ({ user }) => {
  // Muestra al usuario. No se requiere estado de carga
  return (
    <Layout>
      <h1>Tu Perfil</h1>
      <pre>{JSON.stringify(user, null, 2)}</pre>
    </Layout>
  )
}

export default Profile

Una ventaja de este patrón es prevenir destellos de contenido no autenticado antes de redirigir. Es importante notar que obtener datos del usuario en getServerSideProps bloqueará el renderizado hasta que la solicitud a tu proveedor de autenticación se resuelva. Para evitar crear un cuello de botella y aumentar tu TTFB (Tiempo hasta el Primer Byte), debes asegurarte que tu búsqueda de autenticación sea rápida. De lo contrario, considera generación estática.

Proveedores de Autenticación

Ahora que hemos discutido los patrones de autenticación, veamos proveedores específicos y cómo se usan con Next.js.

Trae tu Propia Base de Datos

Ejemplos

Si tienes una base de datos existente con datos de usuarios, probablemente querrás utilizar una solución de código abierto que sea agnóstica al proveedor.

  • Si quieres una utilidad de sesión de bajo nivel, encriptada y sin estado, usa iron-session.
  • Si quieres un sistema de autenticación completo con proveedores incorporados (Google, Facebook, GitHub...), JWT, JWE, email/contraseña, enlaces mágicos y más... usa next-auth.

Ambas bibliotecas soportan cualquiera de los patrones de autenticación. Si estás interesado en Passport, también tenemos ejemplos para él usando cookies seguras y encriptadas:

Otros Proveedores

Para ver ejemplos con otros proveedores de autenticación, revisa la carpeta de ejemplos.

Ejemplos