この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。
こんにちは。データアナリティクス事業本部 サービスソリューション部の北川です。
Amplifyは、@aws-amplify/ui-reactを提供しているので、自分でUIを作成しなくても、簡単に認証機能、画面を実装することができます。
ただ今回は、amplifyを触るのが初めてということもあり、中身を確認するためにも、他のUIライブラリを用いて認証画面を作成してみました。
amplify authの設定
Next.jsとMantine UIを使って、実装していきます。
プロジェクトの作成
$ npx create-next-app --ts
任意のプロジェクト名を付けて、移動します。
$ cd auth-sample
amplifyの環境を作成
$ amplify init
? Initialize the project with the above configuration? No
? Enter a name for the environment dev
? Choose your default editor: Visual Studio Code
? Choose the type of app that you're building javascript
Please tell us about your project
? What javascript framework are you using react
? Source Directory Path: src
? Distribution Directory Path: .next
? Build Command: npm run-script build
? Start Command: npm run-script start
Using default provider awscloudformation
? Select the authentication method you want to use: AWS profile
Distribution Directory Pathの値を.nextに変更し、他の値はデフォルトにします。
profileはamplify configureで作成したものを選択してください。初めての場合は、コンソールが開きますので手順に従ってprofileの作成をします。
認証機能を追加します。
$ amplify add auth
認証構成、認証方法、詳細設定について聞かれますので、今回は以下のように設定しました。
Using service: Cognito, provided by: awscloudformation
The current configured provider is Amazon Cognito.
Do you want to use the default authentication and security configuration? Default configuration
Warning: you will not be able to edit these selections.
How do you want users to be able to sign in? Username
Do you want to configure advanced settings? No, I am done.
✅ Successfully added auth resource signsampleb4cf2245 locally
設定を反映します。
$ amplify push -y
AWS Cognitoでユーザープールを確認します。amplify console
で、AWSのコンソール画面を開くことができます。
ユーザープールが作成されています。
フロントエンドの実装
amplifyをフロントエンドで使用できるよう、インストールします。
$ yarn add aws-amplify
UIライブラリのMantineをインストールします。
$ yarn add @mantine/hooks @mantine/form @mantine/core @mantine/next
/pages/index.tsx
import { useRouter } from "next/router";
import { FC, useEffect, useState } from "react";
import Amplify, { Auth } from "aws-amplify";
import awsconfig from "../src/aws-exports";
import { Button, Container, Group, TextInput } from "@mantine/core";
import { useForm } from "@mantine/hooks";
Amplify.configure(awsconfig);
const Home: FC = () => {
const router = useRouter();
const [confirm, setConfirm] = useState(false);
const form = useForm({
initialValues: {
username: "",
email: "",
password: "",
code: "",
},
});
useEffect(() => {
router.prefetch("/profile");
const currentUser = async () => {
try {
const currentUser = await Auth.currentAuthenticatedUser();
if (currentUser) {
router.push("/profile");
}
} catch (error) {
console.log(error);
}
};
currentUser();
}, [router]);
const signUp = async (): Promise<void> => {
try {
await Auth.signUp({
username: form.values.username,
password: form.values.password,
attributes: {
email: form.values.email,
},
});
setConfirm(true);
} catch (error) {
throw new Error();
}
};
const confirmSignUp = async (): Promise<void> => {
const password = form.values.password;
const code = form.values.code;
try {
await Auth.confirmSignUp(form.values.username, code);
await Auth.signIn({ username: form.values.username, password: password });
router.push("/profile");
} catch (error) {
throw new Error();
}
};
return (
<Container style={{ width: 400, height: 200 }}>
<h2> SignUp</h2>
{!confirm ? (
<form onSubmit={form.onSubmit(signUp)}>
<TextInput
required
label="username"
placeholder="your name"
{...form.getInputProps("username")}
/>
<TextInput
required
label="Email"
placeholder="your@email.com"
{...form.getInputProps("email")}
/>
<TextInput
required
label="Password"
{...form.getInputProps("password")}
/>
<Group position="right" mt="md">
<Button type="submit">SignUp</Button>
</Group>
</form>
) : (
<form onSubmit={form.onSubmit(confirmSignUp)}>
<TextInput required label="Code" {...form.getInputProps("code")} />
<Group position="right" mt="md">
<Button type="submit">Submit</Button>
</Group>
</form>
)}
</Container>
);
};
export default Home;
confirmSignUpは、認証コードの一致を確認する関数になります。また、currentAuthenticatedUserでログインユーザーの情報を取得できます。
今回は記述しませんが、ログインの際には、signIn関数を使用します。
const signIn = async (): Promise<void> => {
try {
await Auth.signIn({ username: form.values.username, password: form.values.password });
router.push("/profile");
} catch (error) {
throw new Error();
}
};
簡単に、ログイン後のページも実装します。
/pages/profile
import { useRouter } from "next/router";
import { useState, useEffect, FC } from "react";
import Amplify, { Auth } from "aws-amplify";
import { CognitoUserInterface } from "@aws-amplify/ui-components";
import awsconfig from "../src/aws-exports";
import { Button, Container, Group } from "@mantine/core";
Amplify.configure(awsconfig);
const Profile: FC = () => {
const router = useRouter();
const [user, setUser] = useState<CognitoUserInterface | undefined>();
useEffect(() => {
const confirmUser = async () => {
const currentUser = await Auth.currentAuthenticatedUser();
if (!currentUser) {
router.push("/");
}
setUser(currentUser);
};
confirmUser();
}, [router]);
const signOut = async (): Promise<void> => {
try {
await Auth.signOut();
} catch (error) {
throw new Error();
}
router.push("/");
};
return (
<Container style={{ width: 400, height: 200 }}>
<h2>UserName : {user?.username}</h2>
<Group position="left" mt="md">
<Button type="submit" onClick={signOut}>
SignOut
</Button>
</Group>
</Container>
);
};
export default Profile;
開発環境で、機能確認をしてみます。
$ yarn dev
サインアップ画面
認証コード
サインアップ後
AWSのコンソールでも確認してみます。
ユーザーが登録されていますね。
まとめ
今回、バリデーションなどの記述はしていませんが、必要最低限の認証機能をMantine UIを使って実装することができました。 Amplifyには他にも、API、ホスティングなどの機能もあるので、今後も色々試してみたいと思います。
ではまた。