

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# Amazon Cognito にカスタム属性を送信し、トークンに挿入する
<a name="send-custom-attributes-cognito"></a>

*Carlos Alessandro Ribeiro と Mauricio Mendoza、Amazon Web Services*

## 概要
<a name="send-custom-attributes-cognito-summary"></a>

Amazon Cognito 認証プロセスにカスタム属性を送信すると、アプリケーションに追加のコンテキストが提供され、より詳細なアクセス制御が可能になり、ユーザープロファイルと認証要件の管理が容易になります。これらの機能は、さまざまなアプリケーションやシナリオで役立ち、アプリケーションの全体的なセキュリティと機能の向上につながります。

このパターンは、アプリケーションが[アクセストークン](https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-the-access-token.html)または [アイデンティティ (ID) トークン](https://docs.aws.amazon.com/cognito/latest/developerguide/amazon-cognito-user-pools-using-the-id-token.html)に追加のコンテキストを提供する必要がある場合に、Amazon Cognito 認証プロセスにカスタム属性を送信する方法を示しています。Node.js をバックエンドアプリケーションとして使用します。アプリケーションは Amazon Cognito [ユーザープール](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools.html)からユーザーを認証し、トークン生成に必要なカスタム属性を渡します。Amazon Cognito の [AWS Lambda トリガー](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-working-with-lambda-triggers.html)を使用すると、コードの大幅なカスタマイズなどの多大な労力をかけることなく認証プロセスをカスタマイズできます。

**重要**  
このパターンのコードとサンプルは、デモンストレーションのみを目的としているため、実稼働ワークロードには推奨されません。実稼働ワークロードの場合、クライアント側で追加の設定が必要です。このパターンは、パイロットまたは概念実証の目的でのみ参照してください。

## 前提条件と制限
<a name="send-custom-attributes-cognito-prereqs"></a>

**前提条件**
+ アクティブな AWS アカウント
+ Amazon Cognito ユーザープールと AWS Lambda 関数を作成および管理するためのアクセス許可
+ AWS Command Line Interface (AWS CLI)、[インストール](https://docs.aws.amazon.com/cli/latest/userguide/getting-started-install.html)および[設定](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-configure.html)済み
+ Node.js をサポートする統合開発環境 (IDE)
+ Node.js バージョン 18 以降が[インストールされていること](https://nodejs.org/en/download/)
+ npm バージョン 8 以降が[インストールされていること](https://docs.npmjs.com/getting-started)
+ TypeScript が[インストールされていること](https://www.typescriptlang.org/download/)

**制限事項**
+ このパターンは、クライアント認証情報の認証フローを介したアプリケーション統合には適用されません。
+ トークン生成前トリガーは、アクセストークンと ID トークンの一部の属性のみを追加または変更できます。詳細については、Amazon Cognito ドキュメントの「[Pre token generation Lambda trigger](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-pre-token-generation.html)」を参照してください。

## アーキテクチャ
<a name="send-custom-attributes-cognito-architecture"></a>

**ターゲットアーキテクチャ**

このパターンのターゲットアーキテクチャを次の図に示します。また、Node.js アプリケーションがバックエンドと連携してデータベースを更新する方法も示します。ただし、バックエンドデータベースの更新はこのパターンの範囲外です。

![Amazon Cognito ユーザープールにカスタム属性を持つアクセストークンを発行する Node.js アプリケーション。](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/images/pattern-img/9f0855e6-77f9-48c2-846e-f9c317127e1f/images/8c52c88b-8954-4b4c-aed3-fd8c22f84c1d.png)


この図表は、次のワークフローを示しています:

1. Node.js アプリケーションは、カスタム属性を持つアクセストークンを Amazon Cognito ユーザープールに発行します。

1. Amazon Cognito ユーザープールは、アクセストークンと ID トークンをカスタマイズするトークン生成前 Lambda 関数を開始します。

1. Node.js アプリケーションは、Amazon API Gateway を介して API コールを行います。

**注記**  
このアーキテクチャに表示される他のアーキテクチャコンポーネントは、例を目的としたもので、このパターンの範囲外です。

**自動化とスケール**

、、[HashiCorp Terraform](https://www.terraform.io/docs)、またはサポートされている Infrastructure as Code (IaC) ツールを使用して、Amazon Cognito ユーザープール、 AWS Lambda 関数[AWS CloudFormation](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/Welcome.html)[AWS Cloud Development Kit (AWS CDK)](https://docs.aws.amazon.com/cdk/v2/guide/home.html)、データベースインスタンス、およびその他のリソースのプロビジョニングを自動化できます。デプロイをスケールする場合は、継続的インテグレーションおよび継続的デリバリー (CI/CD) パイプラインを使用します。これにより、手動デプロイに関連するエラーを防ぐことができます。

## ツール
<a name="send-custom-attributes-cognito-tools"></a>

**AWS のサービス**
+ 「[Amazon API Gateway](https://docs.aws.amazon.com/apigateway/latest/developerguide/welcome.html)」は、任意のスケールで REST、HTTP、WebSocket API を作成、公開、維持、監視、保護する上で役立ちます。
+ [Amazon Cognito](https://docs.aws.amazon.com/cognito/latest/developerguide/what-is-amazon-cognito.html) は、ウェブおよびモバイルアプリの認証、認可、およびユーザー管理機能を提供します。
+ 「[Amazon Elastic Container Service (Amazon ECS)](https://docs.aws.amazon.com/AmazonECS/latest/developerguide/Welcome.html)」 は、クラスターでのコンテナの実行、停止、管理を支援する、高速でスケーラブルなコンテナ管理サービスです。
+ [AWS Lambda](https://docs.aws.amazon.com/lambda/latest/dg/welcome.html) は、サーバーのプロビジョニングや管理を行うことなくコードを実行できるコンピューティングサービスです。必要に応じてコードを実行し、自動的にスケーリングするため、課金は実際に使用したコンピューティング時間に対してのみ発生します。
+ [AWS SDK for JavaScript](https://docs.aws.amazon.com/sdk-for-javascript/v3/developer-guide/welcome.html) は JavaScript API を提供します AWS のサービス。JavaScript API を使用して、Node.js またはブラウザ用のライブラリまたはアプリケーションを構築できます。

**その他のツール**
+ [Node.js](https://nodejs.org/en/docs/) は、スケーラブルなネットワークアプリケーションを構築するために設計された、イベント駆動型の JavaScript ランタイム環境です。
+ [npm](https://docs.npmjs.com/about-npm) は Node.js 環境で動作するソフトウェアレジストリで、パッケージの共有や借用、プライベートパッケージのデプロイ管理に使用されます。

## ベストプラクティス
<a name="send-custom-attributes-cognito-best-practices"></a>

ACM のベストプラクティスを実装することをおすすめします。
+ **シークレットと機密データ** – アプリケーション内にシークレットや機密データを保存しないでください。[AWS AppConfig](https://docs.aws.amazon.com/appconfig/latest/userguide/what-is-appconfig.html)、[AWS Secrets Manager](https://docs.aws.amazon.com/secretsmanager/latest/userguide/intro.html)、または [AWS Systems Manager Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html) など、アプリケーションがデータを取得できる外部システムを使用します。
+ **標準化されたデプロイ** – CI/CD パイプラインを使用してアプリケーションをデプロイします。[AWS CodeBuild](https://docs.aws.amazon.com/codebuild/latest/userguide/welcome.html) や [AWS CodePipeline](https://docs.aws.amazon.com/codepipeline/latest/userguide/welcome.html) などのサービスを使用できます。
+ **トークンの有効期限** – アクセストークンの短い有効期限を設定します。
+ **安全な接続を使用する** – クライアントアプリケーションとバックエンド間のすべての通信は、SSL/TLS を使用して暗号化する必要があります。[AWS Certificate Manager (ACM)](https://docs.aws.amazon.com/acm/latest/userguide/acm-overview.html) を使用して SSL/TLS 証明書を生成および管理し、[Amazon CloudFront](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/Introduction.html) または [Elastic Load Balancing](https://docs.aws.amazon.com/elasticloadbalancing/latest/userguide/what-is-load-balancing.html) を使用して SSL/TLS の終了を処理します。
+ **ユーザー入力を検証する** – インジェクション攻撃やその他のセキュリティの脆弱性を防ぐために、すべてのユーザー入力が検証されていることを確認します。Amazon API Gateway や [AWS WAF](https://docs.aws.amazon.com/waf/latest/developerguide/what-is-aws-waf.html#waf-intro) などの入力検証ライブラリとサービスを使用して、一般的な攻撃ベクトルを防止します。
+ **IAM ロール**を使用する – [AWS Identity and Access Management (IAM)](https://docs.aws.amazon.com/IAM/latest/UserGuide/introduction.html) ロールを使用して AWS リソースへのアクセスを制御し、承認されたユーザーのみがアクセスできるようにします。最小特権の原則に従い、各ユーザーにロールを実行するために必要なアクセス許可のみがあることを確認します。
+ **パスワードポリシーを使用する** – 最小の長さ、複雑さ、有効期限などのセキュリティ要件を満たすパスワードポリシーを設定します。Secrets Manager または AWS Systems Manager Parameter Store を使用して、パスワードを安全に保存および管理します。
+ **多要素認証 (MFA) を有効にする** – MFA を有効にして、すべてのユーザーのセキュリティを強化し、不正アクセスのリスクを軽減します。[AWS IAM アイデンティティセンター](https://docs.aws.amazon.com/singlesignon/latest/userguide/what-is.html) または Amazon Cognito を使用して、MFA やその他の認証方法を有効にします。
+ **機密情報を安全に保存する** – [AWS Key Management Service (AWS KMS)](https://docs.aws.amazon.com/kms/latest/developerguide/overview.html) やその他の暗号化サービスを使用して、パスワードやアクセストークンなどの機密情報を安全に保存します。
+ **強力な認証方法を使用する** – 認証プロセスのセキュリティを強化するには、生体認証や多要素認証などの強力な認証方法を使用します。
+ **疑わしいアクティビティのモニタリング** – [AWS CloudTrail](https://docs.aws.amazon.com/awscloudtrail/latest/userguide/cloudtrail-user-guide.html) およびその他のモニタリングツールを使用して、疑わしいアクティビティや潜在的なセキュリティ脅威をモニタリングします。異常なアクティビティの自動アラートを設定し、[Amazon GuardDuty](https://docs.aws.amazon.com/guardduty/latest/ug/what-is-guardduty.html) または [AWS Security Hub CSPM](https://docs.aws.amazon.com/securityhub/latest/userguide/what-is-securityhub.html) を使用して潜在的な脅威を検出します。
+ **セキュリティポリシーを定期的に見直して更新する** – セキュリティポリシーと手順を定期的に見直して更新し、変化するセキュリティ要件とベストプラクティスを満たしていることを確認します。を使用して AWS Config 、セキュリティポリシーと手順の変更を追跡および監査します。
+ **自動サインアップ** – Amazon Cognito ユーザープールへの自動サインアップを有効にしないでください。詳細については、[Amazon Cognito ユーザープールによるユーザーサインアップ詐欺と SMS ポンピングのリスクを軽減する](https://aws.amazon.com/blogs/security/reduce-risks-of-user-sign-up-fraud-and-sms-pumping-with-amazon-cognito-user-pools/)」(AWS ブログ記事) を参照してください。

その他のベストプラクティスについては、Amazon Cognito ドキュメントの「[Security best practices for Amazon Cognito user pools](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-security-best-practices.html)」を参照してください。

## エピック
<a name="send-custom-attributes-cognito-epics"></a>

### AWS リソースをセットアップする
<a name="set-up-the-aws-resources"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| ユーザープールの作成 | [See the AWS documentation website for more details](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/send-custom-attributes-cognito.html)でユーザープールを設定する方法の詳細と手順については AWS マネジメントコンソール、[「ユーザープールの開始方法」および「ユーザープールに機能とセキュリティオプションを追加する](https://docs.aws.amazon.com/cognito/latest/developerguide/getting-started-user-pools.html)」を参照してください。 [https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-next-steps.html](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-next-steps.html)コストを削減するには、Essentials プランまたは Lite プランを使用してこのパターンをテストします。詳細については、「[Amazon Cognito 料金](https://aws.amazon.com/cognito/pricing/)」を参照してください。 | アプリ開発者、AWS DevOps | 
| ユーザープールにユーザーを追加します。 | 次のコマンドを入力して、Amazon Cognito ユーザープールに 1 人のユーザーを作成します。<pre>aws cognito-idp sign-up \<br />   --client-id <ClientID> \<br />   --username <jane@example.com> \<br />   --password <PASSWORD> \<br />   --user-attributes Name="email",Value="<jane@example.com>" Name="name",Value="<Jane>"</pre> | アプリ開発者、AWS DevOps | 
| ユーザープールにアプリクライアントを追加します。 | [See the AWS documentation website for more details](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/send-custom-attributes-cognito.html) | AWS システム管理者、AWS 管理者、AWS DevOps、アプリケーション開発者 | 
| トークン生成前の Lambda トリガーを作成します。 | [See the AWS documentation website for more details](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/send-custom-attributes-cognito.html) | AWS DevOps、アプリ開発者 | 
| ユーザープールのワークフローをカスタマイズします。 | [See the AWS documentation website for more details](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/send-custom-attributes-cognito.html)詳細については、Amazon Cognito ドキュメントの「[Customizing user pool workflows with Lambda triggers](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-pools-working-with-lambda-triggers.html)」を参照してください。 | AWS DevOps、アプリ開発者 | 

### Node.js アプリケーションを作成する
<a name="create-the-node-js-application"></a>


| タスク | 説明 | 必要なスキル | 
| --- | --- | --- | 
| Node.js アプリケーションを作成します。 | [See the AWS documentation website for more details](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/send-custom-attributes-cognito.html) | アプリ開発者 | 
| 認証ロジックを実装します。 | [See the AWS documentation website for more details](http://docs.aws.amazon.com/ja_jp/prescriptive-guidance/latest/patterns/send-custom-attributes-cognito.html)独自の TypeScript ファイルを作成することも、ユースケースに応じて提供されたサンプルを変更することもできます。 | アプリ開発者 | 
| 環境変数と設定ファイルを構成します。 | ターミナルで、次のコマンドを入力して環境変数を作成します。<pre>export USERNAME="<COGNITO_USER_NAME>"<br />export PASSWORD="<COGNITO_USER_PASSWORD>"<br />export USER_POOL_ID="<COGNITO_USER_ID>"<br />export CLIENT_ID="<COGNITO_CLIENT_ID>"</pre>シークレットをハードコーディングしたり、認証情報を公開したりしないでください。 | アプリ開発者 | 
|  アプリケーションを実行します。 | 次のコマンドを入力してアプリケーションを実行し、アプリケーションが動作していることを確認します。<pre>npm run build<br />npm start</pre> | アプリ開発者 | 
| カスタム属性がトークンに挿入されていることを確認します。 | IDE のデバッグ機能を使用して、アクセストークンと ID トークンを表示します。カスタム属性が追加されていることを確認します。サンプルクエリについては、このパターンの「[追加情報](#send-custom-attributes-cognito-additional)」セクションを参照してください。 | アプリデベロッパー | 

## トラブルシューティング
<a name="send-custom-attributes-cognito-troubleshooting"></a>


| 問題 | ソリューション | 
| --- | --- | 
| ユーザーの認証時の無効なクライアント ID | 通常このエラーは、生成されたクライアントシークレットでクライアント ID を使用している場合に発生します。シークレットをアタッチせずにクライアント ID を作成する必要があります。詳細については、「[Application-specific settings with app clients](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-client-apps.html)」を参照してください。 | 

## 関連リソース
<a name="send-custom-attributes-cognito-resources"></a>
+ [Customizing user pool workflows with Lambda triggers](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html) (Amazon Cognito ドキュメント)
+ [Pre token generation Lambda trigger](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-lambda-pre-token-generation.html) (Amazon Cognito ドキュメント)
+ [CognitoIdentityProviderClient](https://docs.aws.amazon.com/AWSJavaScriptSDK/v3/latest/client/cognito-identity-provider/) (AWS SDK for JavaScript ドキュメント)
+ [cognito-idp](https://awscli.amazonaws.com/v2/documentation/api/2.0.34/reference/cognito-idp/index.html#cli-aws-cognito-idp) (AWS CLI ドキュメント)

## 追加情報
<a name="send-custom-attributes-cognito-additional"></a>

**サンプルの TypeScript ファイル**

次のコードサンプルは、 AWS SDK を使用して Amazon Cognito にカスタム属性を送信することで認証プロセスを呼び出す TypeScript ファイルです。

```
import * as AmazonCognitoIdentity from "amazon-cognito-identity-js";

const userPoolId: string = process.env.USER_POOL_ID ?? '';
const clientId: string = process.env.CLIENT_ID ?? '';

const poolData = {
  UserPoolId: userPoolId,
  ClientId: clientId
};
const userPool = new AmazonCognitoIdentity.CognitoUserPool(poolData);

export const loginWithCognitoSDK = function (userName: string, password: string) {
  const authenticationDetails = new AmazonCognitoIdentity.AuthenticationDetails({
    Username: userName,
    Password: password,
    ClientMetadata: {
        customGroup: "MyCustomGroup",
        customApplicationData: "Custom data from a custom application"
    }
  });
  const userData = {
    Username: userName,
    Pool: userPool
  };

  const cognitoUser = new AmazonCognitoIdentity.CognitoUser(userData);

  // Authenticate the user using the authenticationDetails object
  cognitoUser.authenticateUser(authenticationDetails, {
    onSuccess: function (result: any) {},
    onFailure: function (err: any) {},
  });
}
loginWithCognitoSDK(process.env.USERNAME ?? '', process.env.PASSWORD ?? '');
```

サンプルでは、SDK for JavaScript の `AuthenticationDetails` モデルを使用して、ユーザー名、パスワード、および `ClientMetadada` を指定します。Amazon Cognito での認証後、アクセストークンと ID トークンからクライアントメタデータを取得できます。

**サンプル Lambda 関数**

次のコードサンプルは、Amazon Cognito の[生成前トークン](https://docs.aws.amazon.com/cognito/latest/developerguide/cognito-user-identity-pools-working-with-aws-lambda-triggers.html)にリンクされた Lambda 関数です。Amazon Cognito が使用するアクセストークンと ID トークンをカスタマイズするのに役立ちます。トークンは、アーキテクチャ間の統合を介して渡されます。このサンプルには、`customApplicationData` というカスタム要求属性と `MyCustomGroup` というカスタムグループ名が含まれています。

```
export const handler = async(event, context, callback) => {
    event.response = {
        claimsOverrideDetails: {
            claimsToAddOrOverride: { customApplicationData: event.request.clientMetadata.customApplicationData },
            groupOverrideDetails: { groupsToOverride: [event.request.clientMetadata.customGroup] }
        }
    };
    callback(null, event);
};
```

**アクセストークンサンプル**

アクセストークンをデコードして、追加されたカスタム属性を視覚化できます。以下は、アクセストークンのサンプルです。

```
{
  "sub": "6daf331f-4451-48b4-abde-774579299204",
  "cognito:groups": [
    "MyCustomGroup"
  ],
  "iss": "https://cognito-idp.<REGION>.amazonaws.com/<USERPOOL_ID>",
  "client_id": "<YOUR_CLIENT_ID>",
  "origin_jti": "acff7e91-09f9-4fde-8eec-38b0f8c47cdc",
  "event_id": "c5113a9c-1f01-435b-9b73-a5cd3e88514e",
  "token_use": "access",
  "scope": "aws.cognito.signin.user.admin",
  "auth_time": 1677979246,
  "exp": 1677982846,
  "iat": 1677979246,
  "jti": "5c9c2708-a871-4428-bd9b-18ad261bea90",
  "username": "<USER_NAME>"
}
```

**ID トークンサンプル**

アクセストークンをデコードして、追加されたカスタム属性を視覚化できます。以下は、アクセストークンのサンプルです。

```
{
  "sub": "6daf331f-4451-48b4-abde-774579299204",
  "cognito:groups": [
    "MyCustomGroup"
  ],
  "iss": "https://cognito-idp.<REGION>.amazonaws.com/<USERPOOL_ID>",
  "cognito:username": "<USER_NAME>",
  "origin_jti": "acff7e91-09f9-4fde-8eec-38b0f8c47cdc",
  "customApplicationData": "Custom data from a custom application",
  "aud": "<YOUR_CLIENT_ID>",
  "event_id": "c5113a9c-1f01-435b-9b73-a5cd3e88514e",
  "token_use": "id",
  "auth_time": 1677979246,
  "exp": 1677982846,
  "iat": 1677979246,
  "jti": "f7ca006b-f25b-44d2-a7a4-6e6423f4201f",
  "email": "<USER_EMAIL>"
}
```