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 (
)
}
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.