Name:
interface
Value:
Amplify has re-imagined the way frontend developers build fullstack applications. Develop and deploy without the hassle.

Page updated Jan 25, 2025

Maintenance ModeYou are viewing Amplify Gen 1 documentation. Amplify Gen 1 has entered maintenance mode and will reach end of life on May 1, 2027. New project should use Amplify Gen 2. For existing Gen 1 projects, a migration guide and tooling are available to help you upgrade. Switch to the latest Gen 2 docs →

認証を追加

次に追加する機能は認証です。

Amplifyを使用した認証

Amplifyは認証プロバイダーとしてAmazon Cognitoを使用します。Amazon Cognitoは堅牢なユーザーディレクトリサービスで、ユーザー登録、認証、アカウント復旧などの操作を処理します。このチュートリアルでは、Amazon Cognitoとユーザー名/パスワードログインを使用してアプリケーションに認証を追加する方法を学習します。

認証サービスを作成

アプリに認証を追加するには、以下のコマンドを実行します:

amplify add auth

次のプロンプトのデフォルトを選択します:

? 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.

サービスをデプロイするには、pushコマンドを実行します:

amplify push
✔ Are you sure you want to continue? (Y/n) · yes

これで認証サービスがデプロイされ、使用を開始できます。いつでもプロジェクトにデプロイされたサービスを表示するには、以下のコマンドを実行してAmplify Consoleにアクセスします:

amplify console

ログインUIを作成

AWS に認証サービスがデプロイされたので、アプリに認証を追加する時間です。ログインフローの作成は非常に難しく、時間がかかる場合があります。幸い、Amplify UIにはAuthenticatorコンポーネントがあり、amplifyconfiguration.jsonで指定した設定を使用して、認証フロー全体を提供します。

Amplify UIをインストール

@aws-amplify/ui-reactパッケージには、アプリを構築するために使用するReact固有のUIコンポーネントが含まれています。次のコマンドでインストールします:

npm install @aws-amplify/ui-react

Amplify UI Authenticatorコンポーネントを追加

src/App.tsxまたはsrc/App.jsxを開いて、以下の変更を加えます:

  1. withAuthenticatorコンポーネントをインポートします:
import { withAuthenticator, Button, Heading } from '@aws-amplify/ui-react';
import '@aws-amplify/ui-react/styles.css';
  1. {signOut, user}Appコンポーネントに渡します(TypeScriptの場合は、signOutuserプロップのタイプも追加する必要があります):
import { type AuthUser } from "aws-amplify/auth";
import { type UseAuthenticator } from "@aws-amplify/ui-react-core";
...
type AppProps = {
signOut?: UseAuthenticator["signOut"]; //() => void;
user?: AuthUser;
};
...
const App: React.FC<AppProps> = ({ signOut, user }) => {
// ...
};
const App = ({ signOut, user }) => {
// ...
};
  1. Appコンポーネントの上部にこのヘッディングとボタンブロックを追加します:
return (
<div style={styles.container}>
<Heading level={1}>Hello {user.username}</Heading>
<Button onClick={signOut}>Sign out</Button>
<h2>Amplify Todos</h2>
...
</div>
);
  1. 最後に、AppエクスポートをAmplify UIのwithAuthenticatorコンポーネントでラップします:
export default withAuthenticator(App);

アプリを実行して、アプリを保護する新しい認証フローを確認します:

npm run dev

これで、アプリがユーザーがサインアップおよびサインインできる認証フローと共に読み込まれることがわかります。

完全なコード例をレビュー

以下のコードをすべて示します:

import { useEffect, useState } from "react";
import { generateClient } from "aws-amplify/api";
import { createTodo } from "./graphql/mutations";
import { listTodos } from "./graphql/queries";
import { type CreateTodoInput, type Todo } from "./API";
import { withAuthenticator, Button, Heading } from "@aws-amplify/ui-react";
import { type AuthUser } from "aws-amplify/auth";
import { type UseAuthenticator } from "@aws-amplify/ui-react-core";
import "@aws-amplify/ui-react/styles.css";
const initialState: CreateTodoInput = { name: "", description: "" };
const client = generateClient();
type AppProps = {
signOut?: UseAuthenticator["signOut"]; //() => void;
user?: AuthUser;
};
const App: React.FC<AppProps> = ({ signOut, user }) => {
const [formState, setFormState] = useState<CreateTodoInput>(initialState);
const [todos, setTodos] = useState<Todo[] | CreateTodoInput[]>([]);
useEffect(() => {
fetchTodos();
}, []);
async function fetchTodos() {
try {
const todoData = await client.graphql({
query: listTodos,
});
const todos = todoData.data.listTodos.items;
setTodos(todos);
} catch (err) {
console.log("error fetching todos");
}
}
async function addTodo() {
try {
if (!formState.name || !formState.description) return;
const todo = { ...formState };
setTodos([...todos, todo]);
setFormState(initialState);
await client.graphql({
query: createTodo,
variables: {
input: todo,
},
});
} catch (err) {
console.log("error creating todo:", err);
}
}
return (
<div style={styles.container}>
<Heading level={1}>Hello {user?.username}</Heading>
<Button onClick={signOut}>Sign out</Button>
<h2>Amplify Todos</h2>
<input
onChange={(event) =>
setFormState({ ...formState, name: event.target.value })
}
style={styles.input}
value={formState.name}
placeholder="Name"
/>
<input
onChange={(event) =>
setFormState({ ...formState, description: event.target.value })
}
style={styles.input}
value={formState.description as string}
placeholder="Description"
/>
<button style={styles.button} onClick={addTodo}>
Create Todo
</button>
{todos.map((todo, index) => (
<div key={todo.id ? todo.id : index} style={styles.todo}>
<p style={styles.todoName}>{todo.name}</p>
<p style={styles.todoDescription}>{todo.description}</p>
</div>
))}
</div>
);
};
const styles = {
container: {
width: 400,
margin: "0 auto",
display: "flex",
flexDirection: "column",
justifyContent: "center",
padding: 20,
},
todo: { marginBottom: 15 },
input: {
border: "none",
backgroundColor: "#ddd",
marginBottom: 10,
padding: 8,
fontSize: 18,
},
todoName: { fontSize: 20, fontWeight: "bold" },
todoDescription: { marginBottom: 0 },
button: {
backgroundColor: "black",
color: "white",
outline: "none",
fontSize: 18,
padding: "12px 0px",
},
} as const;
export default withAuthenticator(App);
import { useEffect, useState } from 'react';
import { generateClient } from 'aws-amplify/api';
import { createTodo } from './graphql/mutations';
import { listTodos } from './graphql/queries';
import { withAuthenticator, Button, Heading } from '@aws-amplify/ui-react';
import '@aws-amplify/ui-react/styles.css';
const initialState = { name: '', description: '' };
const client = generateClient();
const App = ({ signOut, user }) => {
const [formState, setFormState] = useState(initialState);
const [todos, setTodos] = useState([]);
useEffect(() => {
fetchTodos();
}, []);
function setInput(key, value) {
setFormState({ ...formState, [key]: value });
}
async function fetchTodos() {
try {
const todoData = await client.graphql({
query: listTodos
});
const todos = todoData.data.listTodos.items;
setTodos(todos);
} catch (err) {
console.log('error fetching todos');
}
}
async function addTodo() {
try {
if (!formState.name || !formState.description) return;
const todo = { ...formState };
setTodos([...todos, todo]);
setFormState(initialState);
await client.graphql({
query: createTodo,
variables: {
input: todo
}
});
} catch (err) {
console.log('error creating todo:', err);
}
}
return (
<div style={styles.container}>
<Heading level={1}>Hello {user.username}</Heading>
<Button onClick={signOut} style={styles.button}>
Sign out
</Button>
<h2>Amplify Todos</h2>
<input
onChange={(event) => setInput('name', event.target.value)}
style={styles.input}
value={formState.name}
placeholder="Name"
/>
<input
onChange={(event) => setInput('description', event.target.value)}
style={styles.input}
value={formState.description}
placeholder="Description"
/>
<button style={styles.button} onClick={addTodo}>
Create Todo
</button>
{todos.map((todo, index) => (
<div key={todo.id ? todo.id : index} style={styles.todo}>
<p style={styles.todoName}>{todo.name}</p>
<p style={styles.todoDescription}>{todo.description}</p>
</div>
))}
</div>
);
};
const styles = {
container: {
width: 400,
margin: '0 auto',
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
padding: 20
},
todo: { marginBottom: 15 },
input: {
border: 'none',
backgroundColor: '#ddd',
marginBottom: 10,
padding: 8,
fontSize: 18
},
todoName: { fontSize: 20, fontWeight: 'bold' },
todoDescription: { marginBottom: 0 },
button: {
backgroundColor: 'black',
color: 'white',
outline: 'none',
fontSize: 18,
padding: '12px 0px'
}
};
export default withAuthenticator(App);
ボーナス: Amplify UIプリミティブを使用

2つのAmplify UIコンポーネントHeadingButtonを使用しました。pタグをTextに、inputTextFieldに、divViewに置き換えることで、アプリの残りをAmplify UIコンポーネントに変換することもできます。

  1. Amplify UIからインポートされたコンポーネントにTextTextFieldViewコンポーネントを追加します:
import {
withAuthenticator,
Button,
Heading,
Text,
TextField,
View
} from '@aws-amplify/ui-react';
  1. AppコンポーネントのpタグをTextに、inputTextFieldに、divViewに置き換えます:
<View style={styles.container}>
<Heading level={1}>Hello {user.username}</Heading>
<Button style={styles.button} onClick={signOut}>
Sign out
</Button>
<Heading level={2}>Amplify Todos</Heading>
<TextField
placeholder="Name"
onChange={(event) => setInput('name', event.target.value)}
style={styles.input}
defaultValue={formState.name}
/>
<TextField
placeholder="Description"
onChange={(event) => setInput('description', event.target.value)}
style={styles.input}
defaultValue={formState.description}
/>
<Button style={styles.button} onClick={addTodo}>
Create Todo
</Button>
{todos.map((todo, index) => (
<View key={todo.id ? todo.id : index} style={styles.todo}>
<Text style={styles.todoName}>{todo.name}</Text>
<Text style={styles.todoDescription}>{todo.description}</Text>
</View>
))}
</View>

Amplify UIの接続されたコンポーネントを使用すると、アプリ全体のスタイルを管理しやすくなります。

この例では、Amplify UIライブラリとwithAuthenticator高次コンポーネントを使用して、実世界の認証フローすぐに開始しました。このコンポーネントをカスタマイズして、フィールドを追加または削除したり、スタイルを更新したり、その他の設定を行ったりすることもできます。必要に応じて関数呼び出しをオーバーライドすることもできます。詳細については、Amplify UIドキュメントウェブサイトにアクセスしてください。

withAuthenticatorに加えて、Amplify Library for JSでカスタム認証フローを構築することもできます。AmplifyのAuthパッケージにはsignUpsignInforgotPasswordsignOutなど、ユーザー認証フローのすべての側面を完全に制御できる複数のメソッドがあります。