Вход и регистрация пользователя NextJS (AWS Cognito)
Цель этого проекта - создать шаблон для NextJS, который позволит мне быстро начать с базы, в которой уже есть встроенная система входа и регистрации. Звучит здорово, эй! P.s. Этот проект будет доступен с открытым исходным кодом на Github, и любой вклад более чем приветствуется!
Приступая к работе
Начнем с того, что я начал с создания простого Extjs с помощью команды NPX.
npx create-next-app next-auth-boilerplate
Я создал проект, используя typescript, eslint, а остальное оставил по умолчанию. (В этом примере я не использую tailwind).
После этого я открыл папку в VS Code, вы также можете выполнить code next-auth-boilerplate
, чтобы сделать это быстрее 😉
Служебные действия
Конечно, мы хотим убедиться, что все красиво и соответствует стандартам в коде, поэтому я пошел дальше и установил prettier, commitlint и husky. (Не собираюсь подробно останавливаться на этом здесь, в этой статье, но вы можете просмотреть git-репозиторий, чтобы просмотреть все конфигурационные файлы, которые я настраиваю, и т.д. ...)
npm i -D husky @commitlint/cli @commitlint/config-conventional prettier
Структура файла
Итак, структура, к которой я пришел, выглядит следующим образом...
(Я включил только файлы и папки, которые я создал, поэтому конфигурационные файлы, файлы package.json и т.д. должны быть там независимо)
├── layouts
│ ├── Footer.tsx
│ ├── Head.tsx
│ └── Header.tsx
├── pages
│ ├── _app.tsx
│ ├── _document.tsx
│ ├── register.tsx
│ └── login.tsx
├── styles
│ ├── Global.scss
│ └── Reset.scss
├── utils
│ ├── Global.scss
│ └── Reset.scss
├── public
├── templates
└── .env
Подготовка к AWS Cognito
Итак, я собираюсь использовать AWS Cognito для обработки пользовательской базы данных. AWS Cognito имеет очень щедрый уровень бесплатности, который позволяет бесплатно получать 50 000 активных пользователей в месяц! Учитывая, что это довольно много, я не думаю, что в ближайшие годы буду платить ни единого пенни ни за один из своих проектов... Это хороший, безопасный вариант, если вы что-то ищете, и он просто значительно упрощает создание систем входа в систему.
Я начинаю с установки Amplify SDK..
npm i @aws-amplify/ui-react aws-amplify
Сделав это, я затем зайду в свой файл .env
и добавлю следующие переменные.
AWS_COGNITO_REGION='{ENTER YOUR REGION e.g eu-west-1}'
AWS_COGNITO_POOL_ID='{ENTER POOL ID}'
AWS_COGNITO_APP_CLIENT_ID='{ENTER CLIENT ID}'
Итак, перейдите в Cognito и настройте пул пользователей. Примечания по каждой из этих переменных...
AWS_COGNITO_REGION - Вы должны быть в состоянии увидеть это в идентификаторе пула в разделе обзора пользовательского пула.
AWS_COGNITO_POOL_ID - Это должно быть видно после нажатия на ваш пул пользователей в обзоре.
AWS_COGNITO_APP_CLIENT_ID - Вы можете найти это в обзоре вашего пула пользователей на вкладке "App integration" и прокрутить вниз до самого низа, и это должно быть там.
Настройка пользовательского пула Cognito в первый раз - непростая задача, но есть множество руководств от AWS, которые помогут в этом. Если вы хотите, чтобы я адаптировал это руководство, включив в него настройку Cognito, дайте мне знать в комментариях!
Наконец, просто слегка адаптируйте next.config.js
файл, содержащий ваш ENV, чтобы сделать его доступным там, где это необходимо. В вашем модуле экспорта добавьте следующее...
env: {
AWS_COGNITO_REGION: process.env.AWS_COGNITO_REGION,
AWS_COGNITO_POOL_ID: process.env.AWS_COGNITO_POOL_ID,
AWS_COGNITO_APP_CLIENT_ID: process.env.AWS_COGNITO_APP_CLIENT_ID,
},
Наконец, я собираюсь просто настроить конфигурацию Amplify... Создайте файл в /utils/aws/Amplify.ts
, а затем скопируйте следующий код, чтобы создать экземпляр Amplify Auth...
import { Amplify } from 'aws-amplify';
Amplify.configure({
Auth: {
region: process.env.AWS_COGNITO_REGION,
userPoolId: process.env.AWS_COGNITO_POOL_ID,
userPoolWebClientId: process.env.AWS_COGNITO_APP_CLIENT_ID,
},
});
а затем перейдите в /pages/_app.tsx
и добавьте оператор импорта вверху следующим образом...
import '@/utils/aws/Amplify';
import type { AppProps } from 'next/app';
export default function App({ Component, pageProps }: AppProps) {
return <Component {...pageProps} />;
}
Создание страницы входа в систему/регистрации
Далее необходимо создать страницу входа в систему и регистрации. В /pages/login.tsx
скопируйте этот готовый код из AWS с несколькими изменениями...
import { Authenticator, useAuthenticator } from '@aws-amplify/ui-react';
import '@aws-amplify/ui-react/styles.css';
import { Auth } from 'aws-amplify';
import { useRouter } from 'next/router';
import { useEffect } from 'react';
const Login = () => {
const router = useRouter();
const { user } = useAuthenticator((context) => [context.user]);
useEffect(() => {
const checkUser = async () => {
try {
const user = await Auth.currentAuthenticatedUser();
if (user) {
router.push('/dashboard');
}
} catch (error) {
// User is not logged in
}
};
checkUser();
}, [router, user]);
return <Authenticator />;
};
export default Login;
Создание HOC аутентификации
Теперь мы продолжим и создадим HOC... (по сути, просто оболочка).
Создайте файл как таковой /utils/withAuth.tsx
и скопируйте и вставьте следующий код.
import { useAuthenticator } from '@aws-amplify/ui-react-core';
import { Auth } from 'aws-amplify';
import { useRouter } from 'next/router';
import { useEffect } from 'react';
const withAuth = (WrappedComponent: any) => {
const WrapperComponent = (props: any) => {
const router = useRouter();
const { user } = useAuthenticator((context) => [context.user]);
useEffect(() => {
const checkAuth = async () => {
try {
await Auth.currentAuthenticatedUser();
} catch (err) {
router.push('/login');
}
};
checkAuth();
}, [router, user]);
return <WrappedComponent {...props} />;
};
return WrapperComponent;
};
export default withAuth;
По сути, то, что мы здесь делаем, - это добавляем useEffect по умолчанию для отслеживания изменений статуса пользователей, т.е. входа в систему / выхода из системы, а затем перенаправляем их на страницу входа в систему, если им нужно снова войти в систему. Здесь мы используем контекст Amplify Authenticator для управления состояниями.
Добавление контекста Authenticator Provider
Говоря о контексте, нам нужно обернуть Authenticator Provider в файл /pages/_app.tsx
. И обновите, чтобы он выглядел как следующий код 👀..
import '@/utils/aws/Amplify';
import { Authenticator } from '@aws-amplify/ui-react';
import type { AppProps } from 'next/app';
export default function App({ Component, pageProps }: AppProps) {
return (
<Authenticator.Provider>
<Component {...pageProps} />
</Authenticator.Provider>
);
}
Защищенные страницы
Наконец, все, что вам нужно сделать сейчас, это добавить все защищенные страницы, которые вы хотите, но убедитесь, что ваша функция экспорта имеет HOC withAuth()
, обернутый вокруг нее! Вот пример приборной панели...
import withAuth from '@/utils/withAuth';
import { Auth } from 'aws-amplify';
const Dashboard = () => {
return (
<div>
<h1>Dashboard Page</h1>
<button onClick={() => Auth.signOut()}>Sign out</button>
</div>
);
};
export default withAuth(Dashboard);
Найдите код на Github
Предлагаем вам изучить нашу статью об улучшении производительности вашего приложения, думаем, это будет интересно.