Аутентификация¶
В предыдущей главе вы завершили создание маршрутов счетов-фактур, добавив проверку формы и улучшив доступность. В этой главе вы добавите аутентификацию в дашборд.
Вот темы, которые мы рассмотрим
- Что такое аутентификация.
- Как добавить аутентификацию в приложение с помощью 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