Перейти к содержанию

Аутентификация (Authentication)

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

Паттерны аутентификации

Паттерн аутентификации определяет стратегию получения данных. Далее необходимо выбрать провайдера аутентификации, который поддерживает выбранную стратегию. Основных паттерна аутентификации два:

  • использование статической генерации для серверной загрузки состояния и получения данных пользователя на стороне клиента
  • получение данных пользователя от сервера во избежание "вспышки" (flash) неаутентифицированного контента (имеется ввиду видимое пользователю переключение состояний приложения)

Аутентификация при статической генерации

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

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

Рассмотрим пример страницы профиля пользователя. На этой странице сначала рендерится шаблон (скелет), а после выполнения запроса на получения данных пользователя, отображаются эти данные:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
// pages/profile.js
import useUser from '../lib/useUser';
import Layout from './components/Layout';

export default function 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>
  );
}

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

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

1
2
3
4
5
export async function getServerSideProps(context) {
  return {
    props: {}, // будут переданы компоненту страницы как пропы
  };
}

Перепишем приведенный выше пример. При наличии сессии компонент Profile получит проп user. Обратите внимание на отсутствие шаблона:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
// pages/profile.js
import withSession from '../lib/session';
import Layout from '../components/Layout';

export const getServerSideProps = withSession(
  async (req, res) => {
    const user = req.session.get('user');

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

    return {
      props: {
        user,
      },
    };
  }
);

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

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

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

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

  • next-iron-session — низкоуровневая закодированная сессия без состояния
  • next-auth — полноценная система аутентификации со встроенными провайдерами (Google, Facebook, GitHub и т. д.), JWT, JWE, email/пароль, магическими ссылками и др.
  • старый-добрый passport:

Комментарии