Page updated Jan 16, 2024

Manage user profiles

User profile management helps you keep your applications secure while also personalizing your app experiences. In this guide we will review how you can enable your users to personalize their profile and verify their contact information. This includes outlining how you can set up user attributes, verify them, and allow your users to delete them when necessary.

Before you begin, you will need:

  • An Amplify project with the Auth category configured
  • The Amplify libraries installed and configured

Set up user attributes

User attributes such as email address, phone number help you identify individual users. Defining the user attributes you include for your user profiles makes user data easy to manage at scale. This information will help you personalize user journeys, tailor content, provide intuitive account control, and more. You can capture information upfront during sign-up or enable customers to update their profile after sign-up. In this section we take a closer look at working with user attributes and how to set them up and manage them.

Enable standard attributes

Amazon Cognito has a set of default standard attributes. To configure and enable standard user attributes using the Amplify CLI in your app, you can run the Amplify amplify add auth command and choose Walkthrough all the auth configurations. If you have previously created your auth resources, you can instead run the amplify update auth command in your terminal. When prompted for Specify read attributes and Specify write attributes, choose the attributes you'd like to enable in your app.

Learn more
Review standard attributes options

There are many user attributes available to use by default in Cognito. Their definitions are based on the OpenID Connect specification:

  • address
  • birthdate
  • email
  • family_name
  • gender
  • given_name
  • locale
  • middle_name
  • name
  • nickname
  • phone_number
  • picture
  • preferred_username
  • profile
  • zoneinfo
  • updated_at
  • website

You can find a list of all the standard attributes here.

Pass user attributes during sign-up

You can create user attributes during or after sign-up. To do this as part of sign-up you can pass them in the attributes object of Auth.signUp function parameters:

import { Auth } from 'aws-amplify'; async function handleSignUp() { try { await Auth.signUp({ username: 'jdoe', password: 'mysecurerandompassword#123', attributes: { email: 'me@domain.com', phone_number: '+12128601234', // E.164 number convention given_name: 'Jane', family_name: 'Doe', nickname: 'Jane' } }); } catch (e) { console.log(e); } }
1import { Auth } from 'aws-amplify';
2
3async function handleSignUp() {
4 try {
5 await Auth.signUp({
6 username: 'jdoe',
7 password: 'mysecurerandompassword#123',
8 attributes: {
9 email: 'me@domain.com',
10 phone_number: '+12128601234', // E.164 number convention
11 given_name: 'Jane',
12 family_name: 'Doe',
13 nickname: 'Jane'
14 }
15 });
16 } catch (e) {
17 console.log(e);
18 }
19}
import { Auth } from 'aws-amplify'; async function handleSignUp() { try { await Auth.signUp({ username: 'jdoe', password: 'mysecurerandompassword#123', attributes: { email: 'me@domain.com', phone_number: '+12128601234', // E.164 number convention given_name: 'Jane', family_name: 'Doe', nickname: 'Jane' } }); } catch (e) { console.log(e); } }
1import { Auth } from 'aws-amplify';
2
3async function handleSignUp() {
4 try {
5 await Auth.signUp({
6 username: 'jdoe',
7 password: 'mysecurerandompassword#123',
8 attributes: {
9 email: 'me@domain.com',
10 phone_number: '+12128601234', // E.164 number convention
11 given_name: 'Jane',
12 family_name: 'Doe',
13 nickname: 'Jane'
14 }
15 });
16 } catch (e) {
17 console.log(e);
18 }
19}

Retrieve user attributes

You can then retrieve user attributes for your users to read in their profile. This helps you personalize their frontend experience as well as control what they will see. Visible attributes will be limited to those you enabled during the Specify read attributes configured with the Auth category. Then you can use the currentAuthenticatedUser method to retrieve user attributes.

const user = await Auth.currentAuthenticatedUser(); const { attributes } = user;
1const user = await Auth.currentAuthenticatedUser();
2
3const { attributes } = user;

Note that if you need to retrieve the latest user attributes after they are changed, you will need to bypass the local cache like so:

const user = await Auth.currentAuthenticatedUser({ bypassCache: true });
1const user = await Auth.currentAuthenticatedUser({
2 bypassCache: true
3});

The bypassCache parameter defaults to false. Alternatively, your users can sign out and sign back in to retrieve and view their latest attributes.

Enable users to update, verify, and delete specific attributes

You can enable your users to update, verify, and delete specific user attributes as their information changes over time. These attributes are enabled as writable when you update the Specify write attributes in your Auth configuration.

Update user attributes

You can enable users to make updates after sign-up by using the updateUserAttributes method:

import { Auth } from 'aws-amplify'; async function updateUserAttributes() { try { const user = await Auth.currentAuthenticatedUser(); const result = await Auth.updateUserAttributes(user, { email: 'me@anotherdomain.com', family_name: 'Lastname' }); console.log(result); // SUCCESS } catch (err) { console.log(err); } }
1import { Auth } from 'aws-amplify';
2
3async function updateUserAttributes() {
4 try {
5 const user = await Auth.currentAuthenticatedUser();
6 const result = await Auth.updateUserAttributes(user, {
7 email: 'me@anotherdomain.com',
8 family_name: 'Lastname'
9 });
10 console.log(result); // SUCCESS
11 } catch (err) {
12 console.log(err);
13 }
14}
import { Auth } from 'aws-amplify'; async function updateUserAttributes() { try { const user = await Auth.currentAuthenticatedUser(); const result = await Auth.updateUserAttributes(user, { email: 'me@anotherdomain.com', family_name: 'Lastname' }); console.log(result); // SUCCESS } catch (err) { console.log(err); } }
1import { Auth } from 'aws-amplify';
2
3async function updateUserAttributes() {
4 try {
5 const user = await Auth.currentAuthenticatedUser();
6 const result = await Auth.updateUserAttributes(user, {
7 email: 'me@anotherdomain.com',
8 family_name: 'Lastname'
9 });
10 console.log(result); // SUCCESS
11 } catch (err) {
12 console.log(err);
13 }
14}

Verify user attributes

If your user changes an attribute that requires confirmation (for example, email or phone number), you will receive a confirmation code for that attribute.

The Auth.updateUserAttributes() function dispatches a hub event to help identify attributes that require verification. You can listen to updateUserAttributes event on auth channel:

import { Hub } from 'aws-amplify'; Hub.listen('auth', ({ payload }) => { if (payload.event === 'updateUserAttributes') { const resultObject = payload.data; } });
1import { Hub } from 'aws-amplify';
2
3Hub.listen('auth', ({ payload }) => {
4 if (payload.event === 'updateUserAttributes') {
5 const resultObject = payload.data;
6 }
7});

You can learn more about how to listen to Hub events here.

For example, below you can see the dispatched resultObject that shows that the email attribute was not updated because it requires verification but the family_name attribute was updated:

{ 'email': { isUpdated: false // indicates that attribute requires verification codeDeliveryDetails: { AttributeName: 'email', DeliveryMedium: 'EMAIL', Destination: 'm***@a...' } }, 'family_name': { isUpdated: true } }
1{
2 'email': {
3 isUpdated: false // indicates that attribute requires verification
4 codeDeliveryDetails: {
5 AttributeName: 'email',
6 DeliveryMedium: 'EMAIL',
7 Destination: 'm***@a...'
8 }
9 },
10 'family_name': {
11 isUpdated: true
12 }
13}

Note: If a user sends several attributes for update and one or more of them is read_only or doesn't exist, the API will throw an error and dispatch an updateUserAttributes_failure Hub event. None of the attributes in the request will be updated.

Updating an email address using Auth.updateUserAttributes will require a verification of the new email address. The user will be emailed a verification code to the updated email address and your application will need to receive the verification code and send it to Auth.verifyCurrentUserAttributeSubmit before the email address will be updated in Cognito.

You can confirm the new email address in your app using the following:

const result = await Auth.verifyCurrentUserAttributeSubmit( 'email', // The attribute name '<verification_code>' );
1const result = await Auth.verifyCurrentUserAttributeSubmit(
2 'email', // The attribute name
3 '<verification_code>'
4);
Example
Full example for email update and confirmation

The React application below implements the flow of updating the email address for the current user when the "Update Email" button is clicked, then provides a form to capture the verification code sent to the user's email.

// App.js import { Authenticator } from '@aws-amplify/ui-react'; import '@aws-amplify/ui-react/styles.css'; import { Auth } from 'aws-amplify'; import { useState } from 'react'; async function updateUserEmail() { try { const user = await Auth.currentAuthenticatedUser(); await Auth.updateUserAttributes(user, { email: 'updatedEmail@mydomain.com' }); console.log('a verification code is sent'); } catch(err) { console.log('failed with error', err); } } async function verifyEmailValidationCode(code: string) { try { await Auth.verifyCurrentUserAttributeSubmit('email', code); console.log('email verified'); } catch(err) { console.log('failed with error', err); } } function ValidationCodeForm() { const [validationCode, setValidationCode] = useState<string | null>(null); return ( <div> <label> Verification Code (sent to the new email): <input onChange={(e) => { setValidationCode(e.target.value); }} type="text" name="vc" /> </label> <button onClick={() => validationCode && verifyEmailValidationCode(validationCode)}> Send Code </button> </div> ); } export default function App() { const [showValidationCodeUI, setShowValidationCodeUI] = useState(false); return ( <Authenticator> {({ signOut, user }) => ( <div className="App"> <div> <pre>{JSON.stringify(user?.attributes, null, 2)}</pre> </div> {showValidationCodeUI === false && ( <button onClick={async () => { await updateUserEmail(); setShowValidationCodeUI(true); } } > Update Email </button> )} {showValidationCodeUI === true && <ValidationCodeForm />} <button onClick={signOut}>Sign out</button> </div> )} </Authenticator> ); }
1// App.js
2import { Authenticator } from '@aws-amplify/ui-react';
3import '@aws-amplify/ui-react/styles.css';
4import { Auth } from 'aws-amplify';
5import { useState } from 'react';
6
7async function updateUserEmail() {
8 try {
9 const user = await Auth.currentAuthenticatedUser();
10 await Auth.updateUserAttributes(user, {
11 email: 'updatedEmail@mydomain.com'
12 });
13
14 console.log('a verification code is sent');
15 } catch(err) {
16 console.log('failed with error', err);
17 }
18}
19
20async function verifyEmailValidationCode(code: string) {
21 try {
22 await Auth.verifyCurrentUserAttributeSubmit('email', code);
23 console.log('email verified');
24 } catch(err) {
25 console.log('failed with error', err);
26 }
27}
28
29function ValidationCodeForm() {
30 const [validationCode, setValidationCode] = useState<string | null>(null);
31 return (
32 <div>
33 <label>
34 Verification Code (sent to the new email):
35 <input
36 onChange={(e) => {
37 setValidationCode(e.target.value);
38 }}
39 type="text"
40 name="vc"
41 />
42 </label>
43 <button onClick={() => validationCode && verifyEmailValidationCode(validationCode)}>
44 Send Code
45 </button>
46 </div>
47 );
48}
49
50export default function App() {
51 const [showValidationCodeUI, setShowValidationCodeUI] = useState(false);
52
53 return (
54 <Authenticator>
55 {({ signOut, user }) => (
56 <div className="App">
57 <div>
58 <pre>{JSON.stringify(user?.attributes, null, 2)}</pre>
59 </div>
60 {showValidationCodeUI === false && (
61 <button
62 onClick={async () => {
63 await updateUserEmail();
64 setShowValidationCodeUI(true);
65 } }
66 >
67 Update Email
68 </button>
69 )}
70 {showValidationCodeUI === true && <ValidationCodeForm />}
71 <button onClick={signOut}>Sign out</button>
72 </div>
73 )}
74 </Authenticator>
75 );
76}
// App.js import { Authenticator } from '@aws-amplify/ui-react'; import '@aws-amplify/ui-react/styles.css'; import { Auth } from 'aws-amplify'; import { useState } from 'react'; async function updateUserEmail() { try { const user = await Auth.currentAuthenticatedUser(); await Auth.updateUserAttributes(user, { email: 'updatedEmail@mydomain.com' }); console.log('a verification code is sent'); } catch (err) { console.log('failed with error', err); } } async function verifyEmailValidationCode(code) { try { await Auth.verifyCurrentUserAttributeSubmit('email', code); console.log('email verified'); } catch (err) { console.log('failed with error', err); } } function ValidationCodeForm() { const [validationCode, setValidationCode] = useState(null); return ( <div> <label> Verification Code (sent to the new email): <input onChange={(e) => { setValidationCode(e.target.value); }} type="text" name="vc" /> </label> <button onClick={() => verifyEmailValidationCode(validationCode)}> Send Code </button> </div> ); } export default function App() { const [showValidationCodeUI, setShowValidationCodeUI] = useState(false); return ( <Authenticator> {({ signOut, user }) => ( <div className="App"> <div> <pre>{JSON.stringify(user.attributes, null, 2)}</pre> </div> {showValidationCodeUI === false && ( <button onClick={async () => { await updateUserEmail(); setShowValidationCodeUI(true); }} > Update Email </button> )} {showValidationCodeUI === true && <ValidationCodeForm />} <button onClick={signOut}>Sign out</button> </div> )} </Authenticator> ); }
1// App.js
2import { Authenticator } from '@aws-amplify/ui-react';
3import '@aws-amplify/ui-react/styles.css';
4import { Auth } from 'aws-amplify';
5import { useState } from 'react';
6
7async function updateUserEmail() {
8 try {
9 const user = await Auth.currentAuthenticatedUser();
10 await Auth.updateUserAttributes(user, {
11 email: 'updatedEmail@mydomain.com'
12 });
13
14 console.log('a verification code is sent');
15 } catch (err) {
16 console.log('failed with error', err);
17 }
18}
19
20async function verifyEmailValidationCode(code) {
21 try {
22 await Auth.verifyCurrentUserAttributeSubmit('email', code);
23 console.log('email verified');
24 } catch (err) {
25 console.log('failed with error', err);
26 }
27}
28
29function ValidationCodeForm() {
30 const [validationCode, setValidationCode] = useState(null);
31 return (
32 <div>
33 <label>
34 Verification Code (sent to the new email):
35 <input
36 onChange={(e) => {
37 setValidationCode(e.target.value);
38 }}
39 type="text"
40 name="vc"
41 />
42 </label>
43 <button onClick={() => verifyEmailValidationCode(validationCode)}>
44 Send Code
45 </button>
46 </div>
47 );
48}
49
50export default function App() {
51 const [showValidationCodeUI, setShowValidationCodeUI] = useState(false);
52
53 return (
54 <Authenticator>
55 {({ signOut, user }) => (
56 <div className="App">
57 <div>
58 <pre>{JSON.stringify(user.attributes, null, 2)}</pre>
59 </div>
60 {showValidationCodeUI === false && (
61 <button
62 onClick={async () => {
63 await updateUserEmail();
64 setShowValidationCodeUI(true);
65 }}
66 >
67 Update Email
68 </button>
69 )}
70 {showValidationCodeUI === true && <ValidationCodeForm />}
71 <button onClick={signOut}>Sign out</button>
72 </div>
73 )}
74 </Authenticator>
75 );
76}

Delete user attributes

Finally, if your users need to delete one or more user attributes, you can call the Auth.deleteUserAttributes method:

import { Auth } from 'aws-amplify'; async function deleteUserAttributes() { try { const user = await Auth.currentAuthenticatedUser(); const result = await Auth.deleteUserAttributes(user, ['family_name']); console.log(result); // SUCCESS } catch (err) { console.log(err); } }
1import { Auth } from 'aws-amplify';
2
3async function deleteUserAttributes() {
4 try {
5 const user = await Auth.currentAuthenticatedUser();
6 const result = await Auth.deleteUserAttributes(user, ['family_name']);
7 console.log(result); // SUCCESS
8 } catch (err) {
9 console.log(err);
10 }
11}

By following the above steps your users can now update, verify, and delete specific user attributes as their information changes over time.

Conclusion

Congratulations! You finished the Manage user profiles guide and your users can now review and customize their profile information.

Next steps

Now that you completed setting up user profile management, you may also want to add some additional features. We recommend: