Реализуйте Google OAuth в своем приложении Next.js с помощью NextAuth.js
В этой статье мы узнаем следующее:
- Использование NextAuth.js с Next.js.
- Сторонняя аутентификация Google с помощью NextAuth.js.
- Поддержание связи между пользователями и таблицами Notes.
- Выполнение операций CRUD с нашей базой данных для чтения и записи заметок.
Вступление
Итак, вы создали потрясающий блог с Next.js, который ежедневно привлекает миллионы пользователей. Чтобы получать доход от написания статей, вам пришла в голову идея заблокировать статьи за платный доступ. Так читатели смогут вас поддержать. Чтобы реализовать такую идею, вам потребуется выполнить следующие шаги:
- Создайте систему входа в систему.
- Убедитесь, что зарегистрированный пользователь подписался на ваш сайт.
- Если они являются платными участниками, позвольте им продолжить наслаждаться вашим контентом.
- С другой стороны, если посетитель не вошел в систему, предложите ему создать учетную запись или войти в систему.
Однако давайте посмотрим правде в глаза: аутентификация - это боль. Для этого требуется тонна кода, а в некоторых случаях обслуживание затруднено.
Здесь на помощь приходит Next-Auth.js. Он не только упрощает процесс создания аутентификации пользователей, но также имеет следующие преимущества:
- Файлы cookie: в паспорте, если вы перезапустите свой сервер, вы автоматически выйдете из системы. В Next-Auth.js это не проблема, поскольку он уже использует файлы cookie для хранения данных сеанса.
- Чрезвычайно безопасный: Next-Auth.js активно продвигает варианты входа без пароля. Кроме того, он использует токены CSRF в своем коде, чтобы гарантировать, что ваш проект не будет содержать эксплойтов и других лазеек.
Пришло время писать код!
Настройка проекта
Инициализация репозитория
Этот шаг довольно прост. Чтобы создать экземпляр проекта Next.js, выполните следующую команду терминала:
Затем создайте файл .env.local
в корне вашего проекта следующим образом:
Здесь мы будем хранить переменные среды.
Теперь приступим к установке наших зависимостей.
Установка модулей
В этом проекте мы будем использовать следующие модули:
next-auth
: Суть нашего проекта. Эта библиотека будет обрабатывать все наши процессы, основанные на аутентификации.mongodb
: Поскольку мы будем использовать сервер MongoDB, Next-Auth.js будет использовать пакетmongodb
как одну из своих зависимостей.mongoose
: Для взаимодействия с нашей базой данных и выполнения операций CRUD с нашими коллекциями.
Чтобы установить эти пакеты, выполните следующую команду терминала:
Давайте теперь инициализируем наш сервер MongoDB.
Настройка MongoDB Atlas
Рекомендую использовать MongoDB Atlas. Он настраивает для вас сервер базы данных в облаке без какой-либо дополнительной настройки.
Сначала войдите на страницу Атласа и выполните следующие действия, чтобы создать свой первый кластер. Когда это будет сделано, нажмите Подключиться:
Затем выберите «Разрешить доступ из любого места»:
Теперь создайте свое имя пользователя и пароль и нажмите «Создать пользователя базы данных», чтобы зарегистрироваться в качестве пользователя. Когда это будет сделано, нажмите «Подключить ваше приложение»:
Затем вы получите строку подключения. Скопируйте это и вставьте в свой .env.local
файл:
Теперь займемся созданием учетных данных Google OAuth.
OAuth с Google
Перейдите в Консоль разработчика Google и нажмите Выбрать проект. Затем нажмите Новый проект:
Когда это будет сделано, перейдите на боковую панель и нажмите «API и службы». Затем нажмите «Панель управления»:
На верхней панели нажмите «Включить API и службы». Вы попадете на страницу библиотеки API. Найдите «Google+» и включите его.
Теперь веб-сайт приведет вас на страницу «Включенные API». Сначала выберите «Учетные данные», а затем щелкните ссылку «Учетные данные в API и службах»:
Это перенаправит вас на домашнюю страницу. Нажмите «Создать учетные данные», а затем «Идентификатор клиента OAuth»:
Выберите «Веб-приложение»:
Теперь дайте вашему приложению имя. Когда это будет сделано, прокрутите вниз до «URI авторизованного перенаправления» и настройте его следующим образом:
Теперь нажмите «Создать», чтобы сообщить Google о создании нашего клиента OAuth. Вы получите свой идентификатор клиента и секрет:
Скопируйте их в свой .env.local
файл следующим образом:
И мы, наконец, закончили! В следующем разделе мы обсудим нашу файловую структуру.
Файловая структура проекта
В корневом каталоге вашего проекта создайте следующие папки:
models
: Будем хранить наши модели Mongoose.helpers
: будет содержать все наши функции промежуточного программного обеспечения.components
: хранит наши пользовательские компоненты, которые можно повторно использовать в других файлах.
Теперь войдите в свою папку pages
и создайте эти папки:
notes
в каталоге/api
: будет обрабатывать/api/notes/
маршруты.auth
в каталоге/api
: будет содержать логику аутентификации пользователя.notes
: будет обрабатывать маршрут/notes
.
В итоге структура вашего проекта должна выглядеть так:
Готово! А теперь давайте попробуем построить внутреннюю часть нашей системы входа в систему.
Создание нашей системы входа в систему
Настройка бэкэнда
В своем проекте перейдите в каталог /pages/api/auth
и создайте файл с именем [...nextauth.js]
. Это означает, что все маршруты, начинающиеся с /api/auth
, будут обрабатываться файлом [...nextauth].js
.
В /pages/api/[...nextauth].js
напишите следующий фрагмент кода:
- Строки 1-2: Импортируйте модуль
NextAuth
для реализации аутентификации. Затем импортируйте пакетProviders
, чтобы сообщить Next.js, что мы будем использовать стороннюю аутентификацию. - Строки 6-11: Сообщите Next.js, что мы будем использовать только Google OAuth для этого проекта. Мы также передаем наш идентификатор Google и секретный ключ через переменные среды.
- Строка 13: используйте наш экземпляр базы данных MongoDB. Строка подключения передается через переменные среды.
- Строка 14: Наш обратный вызов
session
будет запущен, когда пользовательский сеанс будет проверен. - Строка 16. Раскройте свойство сеанса
id
, чтобы мы могли получить к нему доступ. Это будет полезно при создании заметок, связанных с каждым пользователем.
Давайте теперь создадим наш интерфейс.
Создание нашего интерфейса
В /pages/index.js
замените весь свой код следующим:
- Строка 3. Используйте
useSession
Hook, чтобы получить данные вошедшего в систему пользователя. - Строка 7: проверьте, не вошел ли пользователь в систему (если
session
не имеет значения). Если да, предложите пользователю войти в систему. МетодsignIn
обрабатывает функции входа. - Строка 19: Если пользователь вошел в систему (если
session
имеет значение), то показать возможность выхода. МетодsignOut
сделает это за нас. - Строка 21: отображение имени пользователя на главной странице.
Последний шаг - изменить наш _app.js
файл. В /pages/_app.js
сначала импортируйте модуль Provider
следующим образом:
Теперь найдите в /pages/_app.js
следующий фрагмент кода:
Измените это так:
- Строки 2–4: оберните наш
Component
тегамиProvider
. Это сделает наши данные сеанса постоянными на всех маршрутах.
Запустите код. Это будет результат:
Большой! Наш код работает как задумано. Теперь создадим наш Note
компонент.
В итоге ваш /pages/_app.js
файл должен выглядеть так:
Компонент Note
В папке components
создайте файл с именем Note.js
. В этом файле напишите следующий фрагмент кода:
- Строка 4: Наш
Note
компонент будет иметь два свойства:id
иtitle
. - Строка 5: этот
useRouter
экземпляр поможет нам выполнять перенаправление на стороне клиента. - Строка 7: Создайте функцию
sendDelete
. - Строки 8–10: выполнение запроса
DELETE
к маршрутуapi/notes/delete/{id}
. Это скажет серверу идентифицировать нашу запись поid
, а затем удалить ее. - Строка 11: После запроса
DELETE
перенаправьте пользователя на/dashboard
. - Строки 16-21: отобразите опору
title
. Если щелкнуть, перенаправить пользователя на маршрут/notes/{id}
. Это отобразит полную информацию о заметке. - Строки 22-24: перенаправляют пользователя на страницу
/notes/update/${id}
. Это позволит клиенту обновить указанный документ. - Строка 25: Если щелкнуть, вызвать функцию
sendDelete
.
В следующем разделе мы создадим нашу страницу панели инструментов.
Страница панели инструментов
В папке /pages
создайте файл с именем dashboard.js
. В этом файле будут показаны все сохраненные заметки пользователя.
В pages/dashboard.js
напишите следующий код:
- Строка 6:
useSession
Hook сообщит нам, вошел ли пользователь в систему. - Строка 11: отображение приветственного сообщения, если пользователь вошел в систему.
- Строки 13–14: при нажатии пользователь будет перенаправлен на маршрут
notes/add
. - Строка 15: Эта кнопка позволяет пользователю выйти из системы. В случае успеха наше приложение перенаправит их на страницу
/
.
Запустите код. Должен быть результат:
Однако заставлять пользователя вручную переходить на страницу /dashboard
- не очень удобно. Нам нужно это исправить.
В pages/index.js
найдите следующий фрагмент кода:
Измените это так:
- Строка 3: Когда пользователь входит в систему, перенаправьте его на страницу
dashboard
.
Запустите код. Должен быть результат:
Готово! Пришло время создать на его основе наше приложение для создания заметок.
В итоге /pages/index.js
должен выглядеть так:
Приложение "Заметки"
Модель Notes
В папке /models
создайте файл с именем Note.js
. В /models/Note.js
напишите следующий код:
- Строка 3: Определите наш
noteSchema
. - Строка 4: В нашей коллекции будет поле
user
, которое будет связано с вошедшим в систему пользователем. Это позволяет нам создать реляционную базу данных. - Строки 8–9: Наша модель будет иметь поля
title
иbody
, которые будут содержать строковые значения. - Строка 13: Экспортируйте нашу
Note
модель, которая будет производным отnoteSchema
.
Давайте теперь поработаем над связыванием нашей базы данных с этим проектом.
Подключение к базе данных
В папке helpers
создайте файл с именем dbConnect.js
. Как следует из названия, этот файл содержит конфигурацию нашей базы данных.
В helpers/dbConnect.js
напишите следующий код:
- Строки 3–9: Получите нашу строку подключения MongoDB от
.env.local
. Если его нет, то выдает ошибку. - Строка 16: Здесь мы используем Globals для поддержания кэшированного соединения. Это предотвратит рост количества подключений во время использования.
- Строка 28-34: Укажите конфигурацию нашей базы данных.
- Строка 37: подключение к базе данных.
- Строка 45: Наконец, экспортируем нашу
dbConnect
функцию. Теперь мы можем использовать его в нашем проекте.
Мы сделали! Давайте теперь поработаем с CRUD-операциями с нашими заметками.
Добавление заметки
Перейдите в папку /pages/api/notes
и создайте файл с именем add.js
. Этот файл скажет нашей базе данных вставить запись.
В /pages/api/notes/add.js
напишите следующий код:
- Строка 6: Метод
getSession
вернет данные пользователя. - Строка 8: Подключитесь к базе данных перед выполнением любых критически важных для базы данных функций.
- Строка 10: Если клиент не вошел в систему, отправьте сообщение об ошибке.
- Строка 14: Проверить, был ли выполнен запрос
POST
. - Строки 15–16. Если верно, то создайте
Note
документ с полемuser
, указывающим наid
вошедшего в систему пользователя. Это позволяет нам строить отношения. - Строки 17-18: поля
title
иbody
будут содержать введенные пользователем данные. - Строки 21-24: Сохраните документ и выйдите из сохраненной записи.
- Строка 26: Завершить ответ.
Давайте теперь закодируем наш интерфейс для этой функции. В /pages/notes
создайте файл с именем add.js
.
В pages/notes/add.js
напишите следующий код:
- Строка 7: Создайте нашу функцию
addNote
. - Строки 10-19: отправьте
POST
запрос на/api/notes/add
. Это скажет нашему серверу добавить данные в базу данных. Наши поляbody
иtitle
будут иметь значенияinput
. - Строка 20: Когда запрос завершен, перенаправьте пользователя на
/dashboard
. - Строка 26: Когда форма отправлена, вызовите функцию
addNote
.
Запустите код. Должен быть результат:
Посмотрите на консоль:
Это доказывает, что наш документ был сохранен в базе данных. Наш код работает так, как ожидалось.
Теперь мы будем работать над отображением всех наших заметок.
Отображение наших заметок
Давайте сначала разработаем внутренний код этого раздела. В папке /pages/api/notes
создайте файл с именем list.js
. В этом файле напишите следующий код:
- Строка 11: Найдите все заметки пользователя. Это делается путем фильтрации заметок, содержащих поле
user
поляid
текущего пользователя. Наконец, используйте методlean
, чтобы вернуть документы в формате JSON. - Строка 12: отправьте результаты клиенту в формате JSON.
- Строка 13: Если пользователь не вошел в систему, вернуть ошибку.
Теперь поработаем с нашим интерфейсом. В /pages/dashboard.js
добавьте следующий фрагмент кода:
- Строка 1: функция
getServerSideProps
получит данные с сервера. - Строка 3: Создайте наши заголовки, чтобы сообщить NextAuth.js, что мы уполномочены просматривать наши документы.
- Строка 4: Выполните
FETCH
запрос к нашему серверу и отправьте эти заголовки. - Строка 6: Если возвращенные данные содержат ошибку, вместо этого перенаправьте пользователя на маршрут
/
. - Строка 14: отправьте возвращенные данные как реквизиты.
Затем в /pages/dashboard.js
найдите следующий фрагмент кода:
Измените это так:
Теперь мы можем использовать данные, возвращаемые сервером, в нашем компоненте.
В этом же файле найдите свой return
блок:
Замени его так:
- Строка 2: Используйте функцию
map
для отображения наших данных. - Строка 4: Каждый объект будет отображаться с компонентом
Note
.
Запустите код. Должен быть результат:
Наш код работает! Давайте теперь поработаем над чтением конкретного документа.
В итоге /pages/dashboard.js
должно выглядеть так:
Чтение заметки
В качестве первого шага нам нужно закодировать бэкэнд. В каталоге /pages/api/notes
создайте файл с именем [id].js
. Здесь напишите следующий код:
- Строка 10. Найдите заметку пользователя с конкретным
id
. - Строка 12: вернуть документ в формате JSON.
Теперь нам нужно создать наш интерфейс. В папке /pages/notes
создайте файл с именем [id].js
. Это означает, что этот файл будет обрабатывать маршрут /pages/notes/{id}
. Здесь {id}
- это id
нашей заметки.
В /pages/notes/[id].js
напишите следующий код:
- Строка 1: свойство
data
содержит наши данные, которые мы хотим отобразить. - Строки 6-7: отображают поля
title
иbody
нашего объекта. - Строка 14: Создайте функцию
getServerSideProps
для получения данных с сервера. - Строки 18–22: выборка данных из базы данных и их возврат.
- Строки 24-31: Если была ошибка, вместо этого перенаправьте пользователя на
/
. - Строка 33: вернуть данные в компонент
Specific
в качестве свойств.
Запустите код. Должен быть результат:
Большой! Наш код работает так, как ожидалось.
На следующем шаге мы узнаем, как обновлять наши записи.
Обновление заметки
В каталоге /pages/api/note
создайте папку с именем update
. В этой папке создайте файл с именем [id].js
.
В /pages/api/note/update/[id].js
напишите следующий код:
- Строка 11: Проверить, был ли выполнен запрос
GET
. - Строка 12: Если
true
, найдите примечание с совпадающимid
, которое находится в параметре URL-адреса. - Строка 13: Наконец, верните данные в формате JSON.
- Строка 16: Проверить, был ли выполнен запрос
PUT
. - Строка 17: Найдите документ с совпадающим
id
и затем обновите его. - Строка 22: Обновите поля
title
иbody
значениями, введенными пользователем. - Строка 26: Завершить ответ.
Теперь напишем наш интерфейс. В папке /pages/notes
создайте еще один каталог с именем update
. Здесь создайте файл с именем [id].js
.
В /pages/notes/update/[id].js
напишите следующий код:
- Строка 3: Используйте опору
data
в нашем компоненте. Он будет содержать данные с сервера. - Строка 5: извлеките параметр
id
из URL-адреса. - Строка 7: Создайте функцию
updateNote
. - Строка 10: Выполните
PUT
запрос кapi/notes/update
маршруту и отправьте наши входные поляtitle
иbody
в качестве полезной нагрузки. - Строка 20: По завершении запроса перенаправьте пользователя на страницу
/dashboard
.
Когда это будет сделано, добавьте в тот же файл следующий код:
- Строка 6: После отправки формы запустите функцию
updateNote
. - Строки 8-13: Создаем наш
input
элемент. Его начальным значением будет полеtitle
нашей заметки. - Строки 15-20: создайте наш
input
элемент, который будет содержать полеbody
примечания в качестве значения по умолчанию.
В качестве последнего шага нам нужно указать Next.js получить данные. Добавьте в этот файл следующий код:
Этот код функции идентичен коду файла /pages/notes/[id].js
.
Запустите код. Это будет результат:
Вуаля! Результат оказался ожидаемым. Давайте теперь поработаем над удалением нашей записи.
В итоге /pages/notes/update/[id].js
должен выглядеть так:
Удаление записи
В папке /pages/api/notes
создайте каталог с именем delete
. Здесь создайте файл с именем [id].js
.
В /pages/api/notes/delete/[id].js
напишите следующий код:
- Строка 11: Найдите заметку с совпадающими полями
id
иuser
. Если нашел, то удалите. - Строка 20: Завершить ответ.
Запустите код. Должен быть результат:
Готово! Результат оказался ожидаемым.
Дополнительные ресурсы
Репозиторий GitHub
Другой учебный материал
- Аутентификация с помощью NextJS-LogRocket
- Аутентификация NextJS с NextAuth - Джеймс Перкинс
- Создание клона Netflix с помощью Next.Js и Next Auth - Ли Робинсон
Заключение
NextAuth.js упростил разработчикам создание функций аутентификации пользователей в своих приложениях. Как следствие, это улучшает опыт разработчика. Более того, нам не нужно было создавать внешний сервер Express для построения нашей системы входа в систему. Все было сделано в Next.js, что обещало более быстрое и производительное приложение.
Если вы столкнулись с какими-либо проблемами, советую разобрать программу и поиграться с кодом. Спасибо, что дожили до конца!