高度なワークフロー
イベントの購読
ユーザーがサインインまたはサインアウトするときに特定のアクションを実行するには、アプリで認証イベントを購読します。詳細については、Hub Module開発者ガイドを参照してください。
IDプール連携
代わりに、カスタム認証情報プロバイダを作成して、Cognito連携アイデンティティから直接AWS認証情報を取得し、ユーザープール連携を使用しないようにすることができます。Amplify.configureメソッドの呼び出しを通じて、カスタム認証情報プロバイダをAmplifyに提供する必要があります。以下に、このようなカスタムプロバイダを構築する方法のサンプルコードを参照してください。
import { Amplify } from 'aws-amplify';import { fetchAuthSession, CredentialsAndIdentityIdProvider, CredentialsAndIdentityId, GetCredentialsOptions, AuthTokens,} from 'aws-amplify/auth';
// 注:この例は、Cognito認証情報を取得するため、`@aws-sdk/client-cognito-identity`をインストール必要があります// npm add @aws-sdk/client-cognito-identityimport { CognitoIdentity } from '@aws-sdk/client-cognito-identity';
// SDKを使用してidentityIdと認証情報を取得できますconst cognitoidentity = new CognitoIdentity({ region: '<region-from-config>',});
// 注:カスタムプロバイダクラスはCredentialsAndIdentityIdProviderを実装する必要がありますclass CustomCredentialsProvider implements CredentialsAndIdentityIdProvider {
// ログイン情報を保持する例のクラスメンバー federatedLogin?: { domain: string, token: string };
// 連携ログイン情報をロードするカスタムメソッド loadFederatedLogin(login?: typeof this.federatedLogin) { // 必要に応じてキャッシュすることで永続化することもできます this.federatedLogin = login; }
async getCredentialsAndIdentityId( getCredentialsOptions: GetCredentialsOptions ): Promise<CredentialsAndIdentityId | undefined> { try {
// トークンが利用可能かどうかをチェックするための検証を追加できます // 続行する前に期限切れのトークンを更新することもできます
const getIdResult = await cognitoidentity.getId({ // 設定からidentityPoolIdを取得します IdentityPoolId: '<identity-pool-id-from-config>', Logins: { [this.federatedLogin.domain]: this.federatedLogin.token }, });
const cognitoCredentialsResult = await cognitoidentity.getCredentialsForIdentity({ IdentityId: getIdResult.IdentityId, Logins: { [this.federatedLogin.domain]: this.federatedLogin.token }, });
const credentials: CredentialsAndIdentityId = { credentials: { accessKeyId: cognitoCredentialsResult.Credentials?.AccessKeyId, secretAccessKey: cognitoCredentialsResult.Credentials?.SecretKey, sessionToken: cognitoCredentialsResult.Credentials?.SessionToken, expiration: cognitoCredentialsResult.Credentials?.Expiration, }, identityId: getIdResult.IdentityId, }; return credentials; } catch (e) { console.log('認証情報取得エラー: ', e); } } // キャッシュされた認証情報とidentityIdをクリアするために実装します。これは連携サービスからのサインアウト時に呼び出されます。 clearCredentialsAndIdentityId(): void {}}
// カスタムプロバイダのインスタンスを作成しますconst customCredentialsProvider = new CustomCredentialsProvider();Amplify.configure(awsconfig, { Auth: { // カスタム認証情報プロバイダをAmplifyに供給します credentialsProvider: customCredentialsProvider },});カスタム認証情報プロバイダが構築され、Amplify.configureに供給されたので、カスタム認証情報プロバイダを使用してCognitoアイデンティティプールへの連携を完了する方法を見てみましょう。
Facebookサインイン(React)
import React, { useEffect } from 'react';import { fetchAuthSession,} from 'aws-amplify/auth';
// 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; } customCredentialsProvider.loadFederatedLogin({ domain: 'graph.facebook.com', token: response.authResponse.accessToken, }); const fetchSessionResult = await fetchAuthSession(); // 認証情報を返します console.log('fetchSessionResult: ', fetchSessionResult); }, { // 認可されたスコープ scope: 'public_profile,email' } ); } }); }
const createScript = () => { // 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 = () => { // FB SDKクライアントを初期化 const fb = window.FB; fb.init({ appId : 'your_facebook_app_id', cookie : true, xfbml : true, version : 'v2.11' }); }
return ( <div> <button onClick={signIn}>Facebookでサインイン</button> </div> );}Googleサインイン(React)
import React, { useEffect } from 'react';import jwt from 'jwt-decode';import { fetchAuthSession,} from 'aws-amplify/auth';
const SignInWithGoogle = () => { useEffect(() => { // 既存のGoogleクライアント初期化があるかを確認します if (!window.google?.accounts) createScript(); }, []);
// Googleクライアントをロード 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); }
// Googleクライアントを初期化してGoogleボタンをレンダリング const initGsi = () => { if (window.google?.accounts) { window.google.accounts.id.initialize({ client_id: process.env.GOOGLE_CLIENT_ID, callback: (response: any) => { customCredentialsProvider.loadFederatedLogin({ domain: 'accounts.google.com', token: response.credential, }); const fetchSessionResult = await fetchAuthSession(); // 認証情報を返します console.log('fetchSessionResult: ', fetchSessionResult); }, }); window.google.accounts.id.renderButton( document.getElementById('googleSignInButton'), { theme: 'outline', size: 'large' } ); } }
return ( <div> <button id='googleSignInButton'/> </div> );}Auth0との連携
Auth0をCognitoアイデンティティプールのプロバイダの1つとして使用できます。これにより、Auth0経由で認証されたユーザーがAWSリソースにアクセスできるようになります。
手順1. Auth0とCognitoアイデンティティプール統合の説明に従います
手順2. Auth0でログインし、返されたIDトークンを使用して、最初に作成したカスタム認証情報プロバイダを使用してCognito連携アイデンティティプールからAWS認証情報を取得します。
import { fetchAuthSession } from 'aws-amplify/auth';
const { idToken, domain, name, email, phoneNumber } = getFromAuth0(); // auth0からユーザー認証情報と情報を取得します
async function getCognitoCredentials() { try { customCredentialsProvider.loadFederatedLogin({ domain, token: idToken }); const fetchSessionResult = await fetchAuthSession(); // 認証情報を返します console.log('fetchSessionResult: ', fetchSessionResult); } catch (err) { console.log(err); }}Lambda トリガー
defineAuthおよび新しいFunctions実装からのdefineFunctionのtriggersプロパティを使用して、Cognito User PoolのLambda Triggersを定義できます。これにより、登録および認証フローにカスタム機能を追加できます。ここでpreSignUpフック例をチェックしてください。
Pre AuthenticationおよびPre Sign-up Lambdaトリガー
Pre Authentication Lambdaトリガーが有効な場合、signInのオプションとしてclientMetadataを渡すことができます。このメタデータを使用して、認証に関する追加の検証を実装できます。
import { signIn } from 'aws-amplify/auth';
async function handleSignIn(username: string, password: string) { try { await signIn({ username, password, options: { clientMetadata: {} // オプション。任意のキーを含めることができ、Lambda トリガーにそのまま渡されるキーと値のペアのオブジェクト。 } }); } catch (err) { console.log(err); }}他のLambda トリガーへのメタデータの渡し方
多くのCognito Lambda Triggers はclientMetadata属性の形式で、サニタイズされていないキーと値のペアも受け入れます。この属性は、Cognito Lambda Trigger実行をもたらすさまざまなAuth APIに対して指定できます。
これらのAPIには以下が含まれます。
signInsignUpconfirmSignInconfirmSignUpresetPasswordconfirmResetPasswordresendSignUpCodeupdateUserAttributesfetchAuthSession
さらに、ClientMetadataProviderを設定して、内部fetchAuthSession呼び出しにclientMetadataを渡すことができます。
// グローバルclientMetadataを設定(すべてのトークン更新に影響)import { cognitoUserPoolsTokenProvider } from 'aws-amplify/auth/cognito';
const clientMetadataProvider = () => Promise.resolve({ 'app-version': '1.0.0', 'device-type': 'mobile'});
cognitoUserPoolsTokenProvider.setClientMetadataProvider(clientMetadataProvider);validationData属性を受け入れるトリガーの一部はclientMetadataをvalidationDataの値として使用することに注意してください。validationDataに頼っている場合は、clientMetadataを使用するときに注意してください。
AWSサービスオブジェクトの操作
AWS _サービスインターフェースオブジェクト_を使用して、認証状態でAWSサービスを操作できます。Amplify fetchAuthSessionから認証情報をサービス呼び出しコンストラクタに渡すことで、任意のAWSサービスインターフェースオブジェクトのメソッドを呼び出すことができます。
import { fetchAuthSession } from 'aws-amplify/auth';import Route53 from 'aws-sdk/clients/route53';
async function changeResourceRecordSets() { try { const { credentials } = await fetchAuthSession();
const route53 = new Route53({ apiVersion: '2013-04-01', credentials });
// route53オブジェクトを使用した追加のコード //route53.changeResourceRecordSets(); } catch (err) { console.log(err); }}カスタムトークンプロバイダ
AppSync付きOIDC認証など、サービスに独自のトークンを提供したい場合は、カスタムAuth トークンプロバイダを作成します。Amplify.configureメソッド呼び出しを通じてAmplifyにトークンプロバイダを提供する必要があります。以下に、このようなカスタムプロバイダを構築する方法のサンプルコードを参照してください。
import { Amplify } from 'aws-amplify';import { TokenProvider, decodeJWT } from 'aws-amplify/auth';
// ...
const myTokenProvider: TokenProvider = { async getTokens({ forceRefresh } = {}) { if (forceRefresh) { // 可能な場合、新しいトークンの取得を試みます }
const accessTokenString = '<insert JWT from provider>'; const idTokenString = '<insert JWT from provider>'; return { accessToken: decodeJWT(accessTokenString), idToken: decodeJWT(idTokenString), }; },};
Amplify.configure(awsconfig, { Auth: { tokenProvider: myTokenProvider }});API リファレンス
認証モジュールの完全なAPIドキュメントについては、API リファレンスを参照してください。