Amplify has re-imagined the way frontend developers build fullstack applications. Develop and deploy without the hassle.

Page updated Apr 29, 2024

Advanced workflows

Subscribing Events

You can take specific actions when users sign-in or sign-out by subscribing authentication events in your app. Please see our Hub Module Developer Guide for more information.

Identity Pool Federation

You can alternatively use Auth.federatedSignIn() to get AWS credentials directly from Cognito Federated Identities and not use User Pool federation. If you have logged in with Auth.signIn() you can not call Auth.federatedSignIn() as Amplify will perform this federation automatically for you in the background.

In general, if you are using Cognito User Pools to manage user Sign-Up and Sign-In, you should only call Auth.federatedSignIn() when using OAuth flows or the Hosted UI.

import { Auth } from 'aws-amplify';
// To derive necessary data from the provider
const {
token, // the token you get from the provider
domainOrProviderName, // Either the domain of the provider(e.g. accounts.your-openid-provider.com) or the provider name, for now the library only supports 'google', 'facebook', 'amazon', 'developer'
expiresIn, // the time in ms which describes how long the token could live
user, // the user object you defined, e.g. { username, email, phone_number }
identity_id // Optional, the identity id specified by the provider
} = getFromProvider(); // arbitrary function
async function getCognitoCredentials() {
try {
const cred = await Auth.federatedSignIn(
domainOrProviderName,
{
token,
identity_id, // Optional
expires_at: expiresIn * 1000 + new Date().getTime() // the expiration timestamp
},
user
);
console.log(cred);
const authenticatedUser = await Auth.currentAuthenticatedUser();
console.log(authenticatedUser);
} catch (err) {
console.log(err);
}
}

Note that this isn't from a Cognito User Pool so the user you get after calling this method is not a Cognito User.

Facebook sign-in (React)

import React, { useEffect } from 'react';
import { Auth } from 'aws-amplify';
// To federated sign in from Facebook
const SignInWithFacebook = () => {
useEffect(() => {
if (!window.FB) createScript();
}, []);
const signIn = () => {
const fb = window.FB;
fb.getLoginStatus((response) => {
if (response.status === 'connected') {
getAWSCredentials(response.authResponse);
} else {
fb.login(
(response) => {
if (!response || !response.authResponse) {
return;
}
getAWSCredentials(response.authResponse);
},
{
// the authorized scopes
scope: 'public_profile,email'
}
);
}
});
};
const getAWSCredentials = (response) => {
const { accessToken, expiresIn } = response;
const date = new Date();
const expires_at = expiresIn * 1000 + date.getTime();
if (!accessToken) {
return;
}
const fb = window.FB;
fb.api('/me', { fields: 'name,email' }, (response) => {
const user = {
name: response.name,
email: response.email
};
getCognitoCredentials(
'facebook',
{ token: accessToken, expires_at },
user
);
});
};
const getCognitoCredentials = async (providerName, federateOptions, user) => {
try {
const credentials = await Auth.federatedSignIn(
providerName,
federateOptions,
user
);
console.log(credentials);
} catch (err) {
console.log(err);
}
};
const createScript = () => {
// load the sdk
window.fbAsyncInit = fbAsyncInit;
const script = document.createElement('script');
script.src = 'https://connect.facebook.net/en_US/sdk.js';
script.async = true;
script.onload = initFB;
document.body.appendChild(script);
};
const initFB = () => {
const fb = window.FB;
console.log('FB SDK initialized');
};
const fbAsyncInit = () => {
// init the fb sdk client
const fb = window.FB;
fb.init({
appId: 'your_facebook_app_id',
cookie: true,
xfbml: true,
version: 'v2.11'
});
};
return (
<div>
<button onClick={signIn}>Sign in with Facebook</button>
</div>
);
};

Facebook Sign-in (React Native - Expo)

import Expo from 'expo';
import React from 'react';
import { Amplify, Auth } from 'aws-amplify';
const App = () => {
const signIn = async () => {
const { type, token, expires } =
await Expo.Facebook.logInWithReadPermissionsAsync(
'YOUR_FACEBOOK_APP_ID',
{
permissions: ['public_profile']
}
);
if (type === 'success') {
// sign in with federated identity
try {
const credentials = await Auth.federatedSignIn(
'facebook',
{ token, expires_at: expires },
{ name: 'USER_NAME' }
);
console.log('get aws credentials', credentials);
} catch (err) {
console.log(err);
}
}
};
// ...
return (
<View style={styles.container}>
<Button title="FBSignIn" onPress={signIn} />
</View>
);
};

Google sign-in (React)

import React, { useEffect } from 'react';
import jwt from 'jwt-decode';
import { Auth } from 'aws-amplify';
const SignInWithGoogle = () => {
useEffect(() => {
// Check for an existing Google client initialization
if (!window.google?.accounts) createScript();
}, []);
// Load the Google client
const createScript = () => {
const script = document.createElement('script');
script.src = 'https://accounts.google.com/gsi/client';
script.async = true;
script.defer = true;
script.onload = initGsi;
document.body.appendChild(script);
}
// Initialize Google client and render Google button
const initGsi = () => {
if (window.google?.accounts) {
window.google.accounts.id.initialize({
client_id: process.env.GOOGLE_CLIENT_ID,
callback: (response: any) => {
getAWSCredentials(response.credential)
},
});
window.google.accounts.id.renderButton(
document.getElementById("googleSignInButton"),
{ theme: "outline", size: "large" }
);
}
}
// Exchange Google token for temporary AWS credentials
const getAWSCredentials = async (credential: string) => {
const token = jwt(credential) as any;
const user = {
email: token.email,
name: token.name
};
await Auth.federatedSignIn(
'google',
{ token: credential, expires_at: token.exp },
user
);
}
return (
<div>
<button id="googleSignInButton"/>
</div>
);
}
import React, { useEffect } from 'react';
import jwt from 'jwt-decode';
import { Auth } from 'aws-amplify';
const SignInWithGoogle = () => {
useEffect(() => {
// Check for an existing Google client initialization
if (!window.google?.accounts) createScript();
}, []);
// Load the Google client
const createScript = () => {
const script = document.createElement('script');
script.src = 'https://accounts.google.com/gsi/client';
script.async = true;
script.defer = true;
script.onload = initGsi;
document.body.appendChild(script);
}
// Initialize Google client and render Google button
const initGsi = () => {
if (window.google?.accounts) {
window.google.accounts.id.initialize({
client_id: process.env.GOOGLE_CLIENT_ID,
callback: (response: any) => {
getAWSCredentials(response.credential)
},
});
window.google.accounts.id.renderButton(
document.getElementById("googleSignInButton"),
{ theme: "outline", size: "large" }
);
}
}
// Exchange Google token for temporary AWS credentials
const getAWSCredentials = async (credential) => {
const token = jwt(credential);
const user = {
email: token.email,
name: token.name
};
await Auth.federatedSignIn(
'google',
{ token: credential, expires_at: token.exp },
user
);
}
return (
<div>
<button id="googleSignInButton"/>
</div>
);
}

Retrieve JWT Tokens

After the federated login, you can retrieve related JWT tokens from the local cache using the Cache module:

Browser sample

import { Cache } from 'aws-amplify';
// Run this after the sign-in
const federatedInfo = Cache.getItem('federatedInfo');
const { token } = federatedInfo;

React Native sample

import { Cache } from 'aws-amplify';
// inside an async function
// Run this after the sign-in
const federatedInfo = await Cache.getItem('federatedInfo');
const { token } = federatedInfo;

Token Refresh

By default, Amplify will automatically refresh the tokens for Google and Facebook, so that your AWS credentials will be valid at all times. But if you are using another federated provider, you will need to provide your own token refresh method:

Note: Automatic token refresh for Google and Facebook is not supported in React Native. Automatic token refresh is supported when used with Cognito User pool.

JWT Token Refresh sample

import { Auth } from 'aws-amplify';
async function refreshToken() {
// refresh the token here and get the new token info
// ......
const data = {
token, // the token from the provider
expires_at, // the timestamp for the expiration
identity_id // optional, the identityId for the credentials
};
return data;
}
Auth.configure({
refreshHandlers: {
developer: refreshToken // the property could be 'google', 'facebook', 'amazon', 'developer', OpenId domain
}
});

Federate with Auth0

You can use Auth0 as one of the providers of your Cognito Identity Pool. This will allow users authenticated via Auth0 have access to your AWS resources.

Step 1. Follow Auth0 integration instructions for Cognito Federated Identity Pools

Step 2. Login with Auth0, then use the id token returned to get AWS credentials from Cognito Federated Identity Pools using Auth.federatedSignIn:

const { idToken, domain, name, email, phoneNumber } = getFromAuth0(); // get the user credentials and info from auth0
const { exp } = decodeJWTToken(idToken); // Please decode the id token in order to get the expiration time
async function getCognitoCredentials() {
try {
const cred = await Auth.federatedSignIn(
domain, // The Auth0 Domain,
{
token: idToken, // The id token from Auth0
// expires_at means the timestamp when the token provided expires,
// here you can derive it from the expiresIn parameter provided,
// then convert its unit from second to millisecond, and add the current timestamp
expires_at: exp * 1000 // the expiration timestamp
},
{
// the user object, you can put whatever property you get from the Auth0
// for example:
name, // the user name
email, // Optional, the email address
phoneNumber // Optional, the phone number
}
);
console.log(cred);
} catch (err) {
console.log(err);
}
}

Step 3. Get the current user and current Credentials:

const user = await Auth.currentAuthenticatedUser();
console.log(user);
const creds = await Auth.currentCredentials();
console.log(creds);
// await Auth.currentSession() does not currently support federated identities. Please store the auth0 session info manually(for example, store tokens into the local storage).

Step 4. You can pass a refresh handler to the Auth module to refresh the id token from Auth0:

async function refreshToken() {
// refresh the token here and get the new token info
// ......
const data = {
token, // the token from the provider
expires_at, // the timestamp when the token expires (in milliseconds)
identity_id // optional, the identityId for the credentials
};
return data;
}
Auth.configure({
refreshHandlers: {
your_auth0_domain: refreshToken
}
});

Lambda Triggers

The CLI allows you to configure Lambda Triggers for your AWS Cognito User Pool. These enable you to add custom functionality to your registration and authentication flows. Read more

Pre Authentication and Pre Sign-up Lambda triggers

If you have a Pre Sign-up or Pre Authentication Lambda trigger enabled, you can pass validationData as one the properties for signUp or signIn. This metadata can be used to implement additional validations around authentication, such as restricting the types of user accounts that can be registered.

import { Auth } from 'aws-amplify';
async function signIn() {
try {
const user = await Auth.signIn({
username, // Required, the username
password, // Optional, the password
validationData // Optional, an object of key-value pairs which can contain any key and will be passed to your Lambda trigger as-is.
});
console.log(user);
} catch (err) {
console.log(err);
}
}

Auto Sign-in Lambda triggers

If you have autoSignIn enabled, you can pass validationData as property for autoSignIn parameter. It is used to implement additional validations for authentication. For example, you might choose to allow or disallow user sign-up based on the user's domain. The Lambda trigger receives the validation data and uses it in the validation process.

Auth.signUp({
username,
password,
attributes: {
email, // optional
phone_number // optional - E.164 number convention
// other custom attributes
},
autoSignIn: {
// optional - enables auto sign in after user is confirmed
enabled: true,
validationData // optional
}
});

Passing metadata to other Lambda triggers

Many Cognito Lambda Triggers also accept unsanitized key/value pairs in the form of a clientMetadata attribute. To configure a static set of key/value pairs, you can define a clientMetadata key in the Auth.configure function. You can also pass a clientMetadata parameter to the various Auth functions which result in Cognito Lambda Trigger execution.

These functions include:

  • Auth.changePassword
  • Auth.completeNewPassword
  • Auth.confirmSignIn
  • Auth.confirmSignUp
  • Auth.forgotPasswordSubmit
  • Auth.resendSignUp
  • Auth.sendCustomChallengeAnswer
  • Auth.signIn
  • Auth.signUp (as a function parameter and part of autoSignIn parameter)
  • Auth.updateUserAttributes
  • Auth.verifyUserAttribute

Please note that some of triggers which accept a validationData attribute will use clientMetadata as the value for validationData. Exercise caution with using clientMetadata when you are relying on validationData.

Working with AWS service objects

You can use AWS Service Interface Objects to work AWS Services in authenticated State. You can call methods on any AWS Service interface object by passing your credentials from Auth object to the service call constructor:

import { Auth } from 'aws-amplify';
import Route53 from 'aws-sdk/clients/route53';
async function changeResourceRecordSets() {
try {
const credentials = await Auth.currentCredentials();
const route53 = new Route53({
apiVersion: '2013-04-01',
credentials: Auth.essentialCredentials(credentials)
});
// more code working with route53 object
//route53.changeResourceRecordSets();
} catch (err) {
console.log(err);
}
}

Full API Documentation for Service Interface Objects is available here.

Note: To work with Service Interface Objects, your Amazon Cognito users' IAM role must have the appropriate permissions to call the requested services.