The next feature you will be adding is authentication. ## Authentication with Amplify Amplify uses [Amazon Cognito](https://aws.amazon.com/cognito/) as the main authentication provider. Amazon Cognito is a robust user directory service that handles user registration, authentication, account recovery & other operations. In this tutorial, you'll learn how to add authentication to your application using Amazon Cognito and username/password login. ## Create authentication service To add authentication to your app, run this command: ```bash amplify add auth ``` Select the defaults for the following prompts: ```console ? 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. ``` To deploy the service, run the `push` command: ```bash amplify push ``` Now, the authentication service has been deployed and you can start using it. To view the deployed services in your project at any time, go to Amplify Console by running the following command: ```bash amplify console ``` ## Create login UI Creating a login flow can be quite difficult and time consuming to get right. Luckily, Amplify UI has an [authentication](https://ui.docs.amplify.aws/react/components/authenticator) component that provides an entire authentication flow for you, using the configuration you specified in **aws-exports.js.** ### Install Amplify UI The `@aws-amplify/ui-react` package includes React specific UI components you'll use to build your app. Install it with this: ```bash npm install @aws-amplify/ui-react ``` ### Add the Amplify UI Authenticator component Open **src/App.js** and make the following changes: 1. Import the `withAuthenticator` component: ```javascript import { withAuthenticator, Button, Heading } from '@aws-amplify/ui-react'; import '@aws-amplify/ui-react/styles.css'; ``` 2. Pass `{signOut, user}` to the `App` component: ```javascript /* src/App.js */ function App({ signOut, user }) { // ... } ``` 3. Add this heading and button block to the top of your `App` component: ```javascript // ... return (
Hello {user.username}

Amplify Todos

//... ``` 4. Lastly, wrap your `App` export with the `withAuthenticator` Amplify UI component: ```javascript export default withAuthenticator(App); ``` Run the app to see the new authentication flow protecting the app: ```bash npm start ``` Now you should see the app load with an authentication flow allowing users to sign up and sign in. Here's all the code below: ```javascript /* src/App.js */ import React, { useEffect, useState } from 'react' import { Amplify, API, graphqlOperation } from 'aws-amplify' 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'; import awsExports from "./aws-exports"; Amplify.configure(awsExports); const initialState = { name: '', description: '' } 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 API.graphql(graphqlOperation(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 API.graphql(graphqlOperation(createTodo, {input: todo})) } catch (err) { console.log('error creating todo:', err) } } return (
Hello {user.username}

Amplify Todos

setInput('name', event.target.value)} style={styles.input} value={formState.name} placeholder="Name" /> setInput('description', event.target.value)} style={styles.input} value={formState.description} placeholder="Description" /> { todos.map((todo, index) => (

{todo.name}

{todo.description}

)) }
) } 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); ``` ### Bonus: Use Amplify UI Primitives You used two Amplify UI components, `Heading` and `Button`. You could also convert the rest of the app to Amplify UI components by replacing the `p` tags with `Text`, the `input`s with `TextField`s and the `div`s with `View`s. 1. Add the `Text`, `TextField`, `View` components to the imported components from Amplify UI: ```javascript import { withAuthenticator, Button, Heading, Text, TextField, View } from '@aws-amplify/ui-react'; ``` 2. Replace the `p` tags with `Text`, the `input`s with `TextField`s and the `div`s with `View`s in your `App` component: ```javascript Hello {user.username} Amplify Todos setInput('name', event.target.value)} style={styles.input} defaultValue={formState.name} /> setInput('description', event.target.value)} style={styles.input} defaultValue={formState.description} /> { todos.map((todo, index) => ( {todo.name} {todo.description} )) } ``` Using Amplify UI components together makes it easier to manage styling across your entire app. In this example, you used the Amplify React UI library and the `withAuthenticator` component to quickly get up and running with a real-world authentication flow. You can also [customize this component](https://ui.docs.amplify.aws/react/components/authenticator/customization) to add or remove fields, update styling, or other configurations. You can even [override function calls](https://ui.docs.amplify.aws/react/components/authenticator/customization#override-function-calls) if needed. In addition to the `withAuthenticator`, you can build [custom authentication flows Amplify Libraries for JS](/lib/auth/getting-started). Amplify's `Auth` class has over 30 methods including `signUp`, `signIn`, `forgotPassword`, and `signOut` that allow you full control over all aspects of the user authentication flow. Check out the complete API [here](https://aws-amplify.github.io/amplify-js/api/classes/authclass.html). In the next section, you'll host your app on the Amplify Console, a hosting service complete with a globally available CDN, atomic deployments, easy custom domains, and CI / CD.