## Using withAuthenticator HOC
For React Native, the simplest way to add authentication flows into your app is to use the `withAuthenticator` Higher Order Component.
`withAuthenticator` automatically detects the authentication state and updates the UI. If the user is signed in, the underlying component (typically your app's main component) is displayed otherwise signin/signup controls are displayed.
> The default implementation uses the Amplify UI styling, for an example of what that looks like out of the box on web and mobile, see [here](https://aws-amplify.github.io/media/ui_library).
Just add these two lines to your `App.js`:
```javascript
import { withAuthenticator } from 'aws-amplify-react-native';
import { Amplify } from 'aws-amplify';
// Get the aws resources configuration parameters
import awsconfig from './aws-exports'; // if you are using Amplify CLI
Amplify.configure(awsconfig);
// ...
export default withAuthenticator(App);
```
Now, your app has complete flows for user sign-in and registration. Since you have wrapped your **App** with `withAuthenticator`, only signed in users can access your app. The routing for login pages and giving access to your **App** Component will be managed automatically.
`withAuthenticator` component renders your App component after a successful user signed in, and it prevents non-sign-in users to interact with your app. In this case, you need to display a _sign-out_ button to trigger the related process.
To display a sign-out button or customize other, set `includeGreetings = true` in the parameter object. It displays a _greetings section_ on top of your app, and a sign-out button is displayed in the authenticated state. Other customization options are also available as properties to the HOC:
```jsx
export default withAuthenticator(App, {
// Render a sign out button once logged in
includeGreetings: true,
// Show only certain components
authenticatorComponents: [MyComponents],
// display federation/social provider buttons
federated: { myFederatedConfig },
// customize the UI/styling
theme: { myCustomTheme }
});
```
## Using the Authenticator Component
The `withAuthenticator` HOC wraps an `Authenticator` component. Using `Authenticator` directly gives you more customization options for your UI.
```jsx
console.log(authState)}
// An object referencing federation and/or social providers
// The federation here means federation with the Cognito Identity Pool Service
// *** Only supported on React/Web (Not React Native) ***
// For React Native use the API Auth.federatedSignIn()
federated={myFederatedConfig}
// A theme object to override the UI / styling
theme={myCustomTheme}
// Hide specific components within the Authenticator
// *** Only supported on React/Web (Not React Native) ***
hide={[
Greetings,
SignIn,
ConfirmSignIn,
RequireNewPassword,
SignUp,
ConfirmSignUp,
VerifyContact,
ForgotPassword,
TOTPSetup,
Loading
]}
// or hide all the default components
hideDefault={true}
// Pass in an aws-exports configuration
amplifyConfig={myAWSExports}
// Pass in a message map for error strings
errorMessage={myMessageMap}
>
// Default components can be customized/passed in as child components. //
Define them here if you used hideDefault={true}
```
## Customize your own components
You can provide custom components to the `Authenticator` as child components in React and React Native.
```jsx
import { Authenticator, SignIn } from 'aws-amplify-react-native';
// The override prop tells the Authenticator that the SignUp component is not hidden but overridden
;
class MyCustomSignUp extends Component {
constructor() {
super();
this.gotoSignIn = this.gotoSignIn.bind(this);
}
gotoSignIn() {
// to switch the authState to 'signIn'
this.props.onStateChange('signIn', {});
}
render() {
return (
{/* only render this component when the authState is 'signUp' */}
{this.props.authState === 'signUp' && (
My Custom SignUp Component
)}
);
}
}
```
You can render the custom component (or not) based on the injected `authState` within your component as well as jump to other states within your component.
```jsx
if (props.onStateChange) props.onStateChange(state, data);
```
> **_The withFederated and Federated components are not supported on React Native_**. Use the API Auth.federatedSignIn() on React Native.
There is also `withGoogle`, `withFacebook`, `withAmazon` components, in case you need to customize a single provider.
#### Wrapping your Component
This will render your App component with _Authenticator_:
```javascript
import { Authenticator } from 'aws-amplify-react-native'; // or 'aws-amplify-react-native'
...
class AppWithAuth extends Component {
render(){
return (
);
}
}
export default AppWithAuth;
```
## Show your App After Sign-in
In the previous example, you'll see the App is rendered even before the user is signed-in. To change this behavior, you can use _Authenticator_ properties. When inside `Authenticator`, the App component automatically receives those properties.
**authState** is the current authentication state (a string):
```
- signIn
- signUp
- confirmSignIn
- confirmSignUp
- forgotPassword
- requireNewPassword
- verifyContact
- signedIn
```
**authData** - additional data within authState; when the state is `signedIn`, it will return a [`CognitoUser`](https://github.com/aws-amplify/amplify-js/blob/main/packages/amazon-cognito-identity-js/index.d.ts#L48) object.
Using the options above, to control the condition for _Authenticator_ to render App component, simply set `_validAuthStates` property:
```javascript
this._validAuthStates = ['signedIn'];
```
Then, in the component's constructor, implement `showComponent(theme) {}` in lieu of the typical `render() {}` method.
## SignUp
The SignUp component provides your users with the ability to sign up. It is included as part of the `Authenticator` component.
Usage: ``
It can also be used as part of the authentication HOC: `export default withAuthenticator(App, { signUpConfig });`
The SignUp Component accepts a 'signUpConfig' object which allows you to customize it.
import react0 from '/src/fragments/ui-legacy/auth/react/sign-up-attributes.mdx';
The signUpFields array in turn consist of an array of objects, each describing a field that will appear in sign up form that your users fill out:
import react1 from '/src/fragments/ui-legacy/auth/react/sign-up-fields.mdx';
A Sample signUpFields attribute would look like the following:
```js
const signUpConfig = {
header: 'My Customized Sign Up',
hideAllDefaults: true,
defaultCountryCode: '1',
signUpFields: [
{
label: 'My custom email label',
key: 'email',
required: true,
displayOrder: 1,
type: 'string'
},
... // and other custom attributes
]
};
export default withAuthenticator(App, { signUpConfig });
```
## Sign up/in with email/phone number
If the user pool is set to allow email addresses/phone numbers as the username, you can then change the UI components accordingly by using `usernameAttributes` [(learn more about the setup)](https://docs.amplify.aws/lib/auth/getting-started/q/platform/js).
When you are using `email` as the username:
```js
import { withAuthenticator, Authenticator } from 'aws-amplify-react';
// When using Authenticator
class App {
// ...
render() {
return ;
}
}
export default App;
// When using withAuthenticator
class App2 {
// ...
}
export default withAuthenticator(App2, { usernameAttributes: 'email' });
```
When you are using `phone number` as the username:
```js
import { Authenticator, withAuthenticator } from 'aws-amplify-react';
class App {
// ...
render() {
return ;
}
}
export default App;
// When using withAuthenticator
class App2 {
// ...
}
export default withAuthenticator(App2, { usernameAttributes: 'phone_number' });
```
**Note:** If you are using custom signUpFields to customize the `username` field, then you need to make sure either the label of that field is the same value you set in `usernameAttributes` or the key of the field is `username`.
For example:
```js
import React, { Component } from 'react';
import { Amplify } from 'aws-amplify';
import awsconfig from './aws-exports';
import { withAuthenticator } from 'aws-amplify-react';
Amplify.configure(awsconfig);
class App extends Component {}
const signUpConfig = {
header: 'My Customized Sign Up',
hideAllDefaults: true,
defaultCountryCode: '1',
signUpFields: [
{
label: 'My user name',
key: 'username',
required: true,
displayOrder: 1,
type: 'string'
},
{
label: 'Password',
key: 'password',
required: true,
displayOrder: 2,
type: 'password'
},
{
label: 'PhoneNumber',
key: 'phone_number',
required: true,
displayOrder: 3,
type: 'string'
},
{
label: 'Email',
key: 'email',
required: true,
displayOrder: 4,
type: 'string'
}
]
};
const usernameAttributes = 'My user name';
export default withAuthenticator(App, {
signUpConfig,
usernameAttributes
});
```