Аутентификация

Аутентификация подтверждает личность пользователя, а авторизация определяет, к каким ресурсам пользователь имеет доступ. Next.js поддерживает несколько шаблонов аутентификации, каждый из которых предназначен для разных сценариев использования. На этой странице рассмотрены все варианты, чтобы вы могли выбрать подходящий в зависимости от ваших требований.

Шаблоны аутентификации

Первый шаг к выбору подходящего шаблона аутентификации — понимание стратегии получения данных, которую вы хотите использовать. Затем можно определить, какие провайдеры аутентификации поддерживают эту стратегию. Существует два основных шаблона:

  • Использование статической генерации для серверного рендеринга состояния загрузки с последующим получением данных пользователя на стороне клиента.
  • Получение данных пользователя на стороне сервера для исключения отображения неаутентифицированного контента.

Аутентификация статически сгенерированных страниц

Next.js автоматически определяет, что страница статическая, если у неё нет блокирующих требований к данным. Это означает отсутствие getServerSideProps и getInitialProps на странице. Вместо этого ваша страница может отображать состояние загрузки с сервера, а затем получать данные пользователя на стороне клиента.

Одно из преимуществ этого подхода — возможность обслуживать страницы из глобального CDN и предзагружать их с помощью next/link. На практике это приводит к более быстрому TTI (Time to Interactive).

Рассмотрим пример страницы профиля. Сначала будет отображаться скелет загрузки. После завершения запроса данных пользователя будет показано его имя:

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

const Profile = () => {
  // Получение данных пользователя на стороне клиента
  const { user } = useUser({ redirectTo: '/login' })

  // Серверный рендеринг состояния загрузки
  if (!user || user.isLoggedIn === false) {
    return <Layout>Загрузка...</Layout>
  }

  // После завершения запроса данных пользователя отображаем их
  return (
    <Layout>
      <h1>Ваш профиль</h1>
      <pre>{JSON.stringify(user, null, 2)}</pre>
    </Layout>
  )
}

export default Profile

Вы можете посмотреть этот пример в действии. Ознакомьтесь с примером with-iron-session, чтобы понять, как это работает.

Аутентификация страниц с серверным рендерингом

Если вы экспортируете асинхронную функцию getServerSideProps из страницы, Next.js будет предварительно рендерить эту страницу при каждом запросе, используя данные, возвращённые getServerSideProps.

export async function getServerSideProps(context) {
  return {
    props: {}, // Будет передано в компонент страницы как props
  }
}

Преобразуем пример профиля для использования серверного рендеринга. Если есть сессия, возвращаем user как пропс в компонент Profile на странице. Обратите внимание, что в этом примере нет состояния загрузки.

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 }) => {
  // Отображаем пользователя. Состояние загрузки не требуется
  return (
    <Layout>
      <h1>Ваш профиль</h1>
      <pre>{JSON.stringify(user, null, 2)}</pre>
    </Layout>
  )
}

export default Profile

Преимущество этого подхода — предотвращение отображения неаутентифицированного контента перед перенаправлением. Важно отметить, что получение данных пользователя в getServerSideProps блокирует рендеринг до завершения запроса к вашему провайдеру аутентификации. Чтобы избежать узких мест и увеличения TTFB (Time to First Byte), убедитесь, что ваш запрос на аутентификацию выполняется быстро. В противном случае рассмотрите вариант статической генерации.

Провайдеры аутентификации

Теперь, когда мы обсудили шаблоны аутентификации, рассмотрим конкретных провайдеров и их использование с Next.js.

Использование собственной базы данных

Примеры

Если у вас есть существующая база данных с данными пользователей, вам, скорее всего, понадобится решение с открытым исходным кодом, не зависящее от провайдера.

  • Если вам нужен низкоуровневый, зашифрованный и не сохраняющий состояние инструмент для работы с сессиями, используйте iron-session.
  • Если вам нужна полнофункциональная система аутентификации со встроенными провайдерами (Google, Facebook, GitHub…), JWT, JWE, email/пароль, волшебными ссылками и другим, используйте next-auth.

Обе эти библиотеки поддерживают любой из шаблонов аутентификации. Если вас интересует Passport, у нас также есть примеры его использования с безопасными и зашифрованными куки:

Другие провайдеры

Чтобы увидеть примеры с другими провайдерами аутентификации, ознакомьтесь с папкой примеров.

Примеры