Аутентификация¶
В предыдущей главе вы завершили создание маршрутов счетов-фактур, добавив проверку формы и улучшив доступность. В этой главе вы добавите аутентификацию в дашборд.
Вот темы, которые мы рассмотрим
- Что такое аутентификация.
- Как добавить аутентификацию в приложение с помощью NextAuth.js.
- Как использовать Middleware для перенаправления пользователей и защиты маршрутов.
- Как использовать
UseActionStateв React для обработки отложенных состояний и ошибок формы.
Что такое аутентификация?¶
Аутентификация - ключевая часть многих современных веб-приложений. С ее помощью система проверяет, является ли пользователь тем, за кого себя выдает.
Безопасный веб-сайт часто использует несколько способов проверки личности пользователя. Например, после ввода имени пользователя и пароля сайт может отправить проверочный код на ваше устройство или использовать внешнее приложение, например Google Authenticator. Такая двухфакторная аутентификация (2FA) помогает повысить уровень безопасности. Даже если кто-то узнает ваш пароль, он не сможет получить доступ к вашей учетной записи без вашего уникального маркера.
Аутентификация и авторизация¶
В веб-разработке аутентификация и авторизация выполняют разные функции:
- Аутентификация - это проверка того, что пользователь является тем, за кого себя выдает. Вы подтверждаете свою личность с помощью чего-то, что у вас есть, например, имени пользователя и пароля.
- Авторизация - это следующий шаг. После того как личность пользователя подтверждена, авторизация определяет, какие части приложения ему разрешено использовать.
Итак, аутентификация проверяет, кто вы, а авторизация определяет, что вы можете делать или к чему можете получить доступ в приложении.
Что из перечисленного ниже лучше всего описывает разницу между аутентификацией и авторизацией?
Создание маршрута входа в систему¶
Начните с создания нового маршрута в вашем приложении под названием /login и вставьте следующий код:
| /app/login/page.tsx | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
Вы заметите, что страница импортирует <LoginForm />, который вы обновите позже в этой главе. Этот компонент обернут в React <Suspense>, потому что он будет получать доступ к информации из входящего запроса (параметры поиска URL).
NextAuth.js¶
Мы будем использовать NextAuth.js для добавления аутентификации в ваше приложение. NextAuth.js абстрагирует большую часть сложностей, связанных с управлением сессиями, входом и выходом из системы, а также другими аспектами аутентификации. Хотя вы можете реализовать эти функции вручную, этот процесс может занять много времени и привести к ошибкам. NextAuth.js упрощает этот процесс, предоставляя унифицированное решение для аутентификации в приложениях Next.js.
Установка NextAuth.js¶
Установите NextAuth.js, выполнив следующую команду в терминале:
| Terminal | |
|---|---|
1 | |
Здесь вы устанавливаете beta версию NextAuth.js, которая совместима с Next.js 14+.
Далее сгенерируйте секретный ключ для вашего приложения. Этот ключ используется для шифрования файлов cookie, обеспечивая безопасность пользовательских сессий. Для этого выполните следующую команду в терминале:
| Terminal | |
|---|---|
1 2 3 | |
Затем в файле .env добавьте сгенерированный ключ в переменную AUTH_SECRET:
| .env | |
|---|---|
1 | |
Чтобы auth работал в продакшне, вам нужно будет обновить переменные окружения и в проекте Vercel. Посмотрите это руководство о том, как добавить переменные окружения в Vercel.
Добавление опции pages¶
Создайте файл auth.config.ts в корне нашего проекта, который экспортирует объект authConfig. Этот объект будет содержать параметры конфигурации для NextAuth.js. Пока что он будет содержать только опцию pages:
| /auth.config.ts | |
|---|---|
1 2 3 4 5 6 7 | |
Вы можете использовать опцию pages, чтобы указать маршрут для пользовательских страниц входа, выхода и ошибок. Это не обязательно, но если добавить signIn: '/login' в опцию pages, пользователь будет перенаправлен на нашу пользовательскую страницу входа, а не на страницу NextAuth.js по умолчанию.
Защита маршрутов с помощью Next.js Middleware¶
Далее добавьте логику для защиты маршрутов. Это не позволит пользователям получить доступ к страницам дашборда, если они не вошли в систему.
| /auth.config.ts | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
Коллбэк authorized используется для проверки того, авторизован ли запрос для доступа к странице с помощью Next.js Middleware. Он вызывается перед завершением запроса и получает объект со свойствами auth и request. Свойство auth содержит сессию пользователя, а свойство request - входящий запрос.
Параметр providers представляет собой массив, в котором перечисляются различные варианты входа в систему. На данный момент это пустой массив, чтобы удовлетворить конфигурацию NextAuth. Подробнее об этом вы узнаете в разделе Добавление провайдера учетных данных.
Далее вам нужно будет импортировать объект authConfig в файл Middleware. В корне вашего проекта создайте файл middleware.ts и вставьте в него следующий код:
| /middleware.ts | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 | |
Здесь вы инициализируете NextAuth.js объектом authConfig и экспортируете свойство auth. Вы также используете опцию matcher из Middleware, чтобы указать, что он должен запускаться по определенным путям.
Преимущество использования Middleware для этой задачи заключается в том, что защищенные маршруты не начнут отрисовываться, пока Middleware не проверит аутентификацию, что повышает как безопасность, так и производительность вашего приложения.
Хеширование паролей¶
Хорошей практикой является хеширование паролей перед их хранением в базе данных. Хеширование преобразует пароль в строку символов фиксированной длины, которая выглядит случайной, обеспечивая уровень безопасности, даже если данные пользователя открыты.
При загрузке базы данных вы использовали пакет bcrypt для хэширования пароля пользователя перед его сохранением в базе данных. Позже в этой главе вы снова будете использовать его для проверки соответствия пароля, введенного пользователем, паролю в базе данных. Однако для пакета bcrypt вам придется создать отдельный файл. Это связано с тем, что bcrypt опирается на API Node.js, недоступные в Next.js Middleware.
Создайте новый файл auth.ts, который будет содержать объект authConfig:
| /auth.ts | |
|---|---|
1 2 3 4 5 6 | |
Добавление провайдера учетных данных¶
Далее вам нужно будет добавить опцию providers для NextAuth.js. providers - это массив, в котором вы перечисляете различные варианты входа в систему, такие как Google или GitHub. В этом курсе мы сосредоточимся на использовании только Credentials provider.
Провайдер Credentials позволяет пользователям входить в систему с помощью имени пользователя и пароля.
| /auth.ts | |
|---|---|
1 2 3 4 5 6 7 8 | |
Полезно знать
Существуют и другие альтернативные провайдеры, такие как OAuth или email. Полный список возможностей см. в документации NextAuth.js.
Добавление функциональности авторизации¶
Вы можете использовать функцию authorize для обработки логики аутентификации. Аналогично Server Actions, вы можете использовать zod для проверки электронной почты и пароля перед тем, как проверить, существует ли пользователь в базе данных:
| /auth.ts | |
|---|---|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
После проверки учетных данных создайте новую функцию getUser, которая будет запрашивать пользователя из базы данных.
| /auth.ts | |
|---|---|
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 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | |
Затем вызовите bcrypt.compare, чтобы проверить, совпадают ли пароли:
| 9-11 28 34 | |
|---|---|
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 35 36 37 38 39 40 41 42 | |
Наконец, если пароли совпадают, вы хотите вернуть пользователя, в противном случае верните null, чтобы пользователь не смог войти в систему.
Обновление формы входа¶
Теперь вам нужно связать логику авторизации с формой входа. В файле actions.ts создайте новое действие под названием authenticate. Это действие должно импортировать функцию signIn из файла auth.ts:
| /app/lib/actions.ts | |
|---|---|
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 | |
Если возникла ошибка 'CredentialsSignin', вы хотите вывести соответствующее сообщение об ошибке. Вы можете узнать об ошибках NextAuth.js в документации.
Наконец, в компоненте login-form.tsx вы можете использовать функцию React useActionState для вызова действия сервера, обработки ошибок формы и отображения ее состояния ожидания:
| app/ui/login-form.tsx | |
|---|---|
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 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 | |
Добавление функции выхода из системы¶
Чтобы добавить функцию выхода из системы в <SideNav />, вызовите функцию signOut из auth.ts в элементе <form>:
| /ui/dashboard/sidenav.tsx | |
|---|---|
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 | |
Попробуйте¶
Теперь попробуйте. Вы должны иметь возможность входить и выходить из приложения, используя следующие учетные данные:
- Email:
[email protected] - Password:
123456
Источник — https://nextjs.org/learn/dashboard-app/adding-authentication