## 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 }); ```