Next.js Firebase authentication - включая SSR

В последнее время я экспериментировал с Next.js. На мой взгляд, это отличная библиотека для запуска и запуска приложения на основе React.
Я просто боролся с аутентификацией моего приложения. Мне нравится использовать службу аутентификации Firebase, поэтому я хотел реализовать ее в приложении Next.js.

Мне нравится думать, что одна из приятных особенностей Next JS - это рендеринг на стороне сервера. Это позволяет мне выполнять все необходимые вызовы моей серверной части или базы данных и отображать статическую веб-страницу на основе данных, полученных этими вызовами. Это помогает с очевидными вещами, такими как SEO, а также, например, для публикации веб-страниц в социальных сетях. Когда вы делитесь веб-страницей в Facebook, она будет сканировать вашу страницу и извлекать некоторые данные предварительного просмотра для встраивания в социальную сеть. Когда часть ваших данных отображается на основе вызовов на стороне клиента, есть большая вероятность, что у Facebook возникнут проблемы со сканированием вашего приложения.

Кроме того, мне нравится то, что мои конечные пользователи не могут просматривать мои вызовы API. Firebase - отличная платформа, которая обеспечивает аутентификацию для ваших приложений. Проверить состояние аутентификации пользователя на стороне клиента действительно легко через Firebase. В какой-то момент мне захотелось проверить состояние аутентификации во время рендеринга страницы на стороне сервера. Я немного боролся, чтобы заставить эту работу работать.

В этой статье я шаг за шагом покажу, как я пришел к своему решению. Как всегда, если вы видите какие-либо проблемы в моем решении или у вас есть интересные дополнения к нему, не стесняйтесь оставлять комментарии ниже!

Стандартный пример

На Github у Next.js есть много хороших примеров. В частности, есть пример, включающий аутентификацию Firebase:



Это хороший пример того, как использовать аутентификацию Firebase, но мне всегда не хватало части здесь. В этом примере они только показывают, как использовать аутентификацию на стороне клиента. Что идеально подходит для вашего варианта использования.

Но когда я смотрю на функциональные возможности Next.js, мне действительно интересны возможности на стороне сервера.

В частности, метод getServerSideProps.

Next.js предоставляет нам функциональность, подобную PHP, в которой мы можем обрабатывать логику на стороне сервера перед рендерингом страницы на клиенте. Это означает, что вы можете обрабатывать некоторые запросы API или бэкэнд-логику непосредственно перед тем, как пользователь увидит страницу. Результат вашей бэкэнд-логики может быть передан через «реквизиты» и может быть использован во фронтенде. У этого есть много преимуществ.

Проблема здесь в том, что я хочу иметь возможность получить состояние аутентификации пользователя. Это то, что не рассматривается в приведенном выше примере Firebase. Хочу поделиться с вами своим решением.

Решение

Итак, что я буду делать в двух словах?

  • Управление аутентификацией Firebase с помощью файла cookie сеанса
  • Настройте конечную точку API аутентификации, которая будет предоставлять cookie со стороны сервера.
  • Используйте Cookie внутри метода getServerSideProps.


Настройка Firebase

Итак, сначала создайте проект Firebase. Получите учетную запись службы и включите аутентификацию по электронной почте. Я не буду подробно объяснять этот шаг.

В одной из моих других историй это подробно объясняется:



Вход - Клиент

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

Увеличим масштаб файла utils / auth.js:

Прежде всего, мы установим постоянство аутентификации Firebase на None. Это потому, что мы будем обрабатывать это сами, используя файл cookie, который будет установлен через наш вызов API.

В методе «signIn» мы используем методы, предоставляемые Firebase, для обработки проверки учетных данных пользователя. «SignInWithEmailAndPassword» делает именно то, о чем говорит его название.

После успешного входа мы выполняем вызов POST, предоставляемый нашим API Next.js. В этом вызове мы предоставляем IDToken, полученный от Firebase. Наша конечная точка API проверяет действительность этого токена и возвращает ответ, включая Cookie, если токен действителен.

Вход - API

В нашем файле pages / api / auth.js мы обработаем входящий запрос POST и проверим действительность Firebase IDToken.

Если токен действителен, мы сгенерируем файл cookie сеанса, который будет возвращен через заголовок Set-Cookie. Это установит cookie для клиента, получающего ответ на вызов.

Обратите внимание на параметры «secure» и «httpOnly», которые помогут защитить файл cookie. Из-за этого к cookie нельзя получить доступ через JavaScript, который защищает пользователя от злонамеренных третьих лиц.

Обратите внимание, что параметр secure не работает в Localhost. Вот почему я поместил его в переменную окружения. В моей производственной среде для этого параметра всегда будет установлено значение true, но при локальном тестировании мне нужно будет установить для этого параметра значение false.

Кроме того, одна из моих больших ошибок при попытке выполнить эту работу, которая отняла у меня очень много времени, оставила параметр пути пустым. При этом путь будет установлен на «/ api», потому что это путь, по которому установлен файл cookie. Из-за этого мне не удалось получить файл cookie в методе getServerSideProps. Изменение этого параметра на «/» решило эту проблему.

Использование состояния аутентификации на стороне сервера

pages / user.js:

Я создал простую демонстрационную страницу, чтобы показать, как мы можем использовать Cookie для проверки аутентификации.

На этом этапе мы узнаем состояние аутентификации до того, как страница будет отображена. Это означает, что мы можем получить некоторые пользовательские данные перед возвратом HTML клиенту.

utils / verifyCookie.js

Эта функция проверит файл cookie сеанса с помощью Firebase SDK:

Пример полного кода - репозиторий GitHub

Вы можете найти полный пример кода на GitHub:
https://github.com/ThomasSwolfs/nextjs-firebase-auth-ssr-example

Я надеюсь, что смогу помочь кому-нибудь с этим решением. Не стесняйтесь подписываться или хлопать, если вам нравится мой контент!

Ваше здоровье

- Томас