LoginSignup
0
0

【AWS】Cognitoのキャリア認証メールの文字化け対応

Last updated at Posted at 2023-10-12

キャリアメール文字化け

CognitoIdentityServiceProviderのadminUpdateUserAttributes関数を用いてメール認証やメール変更を行なっているところ、キャリアメールの場合文字化け現象が起きてしまいました。

原因はキャリアメールの場合、OSのメッセージアプリを使ってメール受信するから、送信者と受信者でメールソフトのエンコードが異なると文字化けが発生してしまいます。

SESマルチパート配信

SESを用いて、マルチパート配信すれば、解決できます。SESマルチパートについて、前の記事に書きましたので、ここでは述べません。

アーキテクチャー

CognitoIdentityServiceProviderのadminUpdateUserAttributesでカスタムEメール送信者Lambdaトリガー起動させて、Lambda関数でSESマルチパート配信を行う
スクリーンショット 2023-10-12 10.37.30.png

Cognito Lambdaトリガーによるマルチパート配信

注意点

  1. カスタムEメール送信者LambdaトリガーはコンソールやCloudFormationから作成できないので、AWS CLIを利用する
  2. カスタムメッセージLambdaトリガーでは「確認コードを配置するためのプレースホルダー」が渡されるが、カスタムEメール送信者Lambdaトリガーでは「KMSキーで暗号化された確認コード」が渡される
  3. 渡されたコードを復号処理しないといけない

本件と関係ないですが、追伸となります:

カスタムメッセージLambdaトリガーでメール送信する際、 Lambda関数にてメール送信処理まで実施する必要はないです。カスタムメッセージレスポンスパラメータを Lambda 関数での return としていただけますと、その内容に基づいて Cognito 側がメール送信処理を実施します。

"response": {
    "smsMessage": "string",
    "emailMessage": "string",
    "emailSubject": "string"
}

KMS Keyを作成する

AWS Key Management Service (AWS KMS) で対称暗号化キーを作成します
スクリーンショット 2023-10-12 10.55.39.png

Lambda作成

カスタム送信者のトリガーとして割り当てる Lambda 関数を作成します。Lambda 関数ロールに対して、KMS キーへの kms:Decrypt アクセス許可を付与します。

const AWS = require('aws-sdk');
const b64 = require('base64-js');
const encryptionSdk = require('@aws-crypto/client-node');
//Configure the encryption SDK client with the KMS key from the environment variables.
const { encrypt, decrypt } = encryptionSdk.buildClient(encryptionSdk.CommitmentPolicy.REQUIRE_ENCRYPT_ALLOW_DECRYPT);
const generatorKeyId = process.env.KEY_ALIAS;
const keyIds = [ process.env.KEY_ARN ];
const keyring = new encryptionSdk.KmsKeyringNode({ generatorKeyId, keyIds })
exports.handler = async (event) => {
	//Decrypt the secret code using encryption SDK.
	let plainTextCode;
	if(event.request.code){
		const { plaintext, messageHeader } = await decrypt(keyring, b64.toByteArray(event.request.code));
		plainTextCode = plaintext
	}
	//PlainTextCode now contains the decrypted secret.
	if(event.triggerSource == 'CustomEmailSender_SignUp'){
		//Send an email message to your user via a custom provider.
		//Include the temporary password in the message.
	}
	else if(event.triggerSource == 'CustomEmailSender_ResendCode'){
	}
	else if(event.triggerSource == 'CustomEmailSender_ForgotPassword'){
	}
	else if(event.triggerSource == 'CustomEmailSender_UpdateUserAttribute'){
	}
	else if(event.triggerSource == 'CustomEmailSender_VerifyUserAttribute'){
	}
	else if(event.triggerSource == 'CustomEmailSender_AdminCreateUser'){
	}
	else if(event.triggerSource == 'CustomEmailSender_AccountTakeOverNotification'){
	}
	return;
};

Lambdaイベントからもらったcodeはkmsキーを用いて復号処理しないといけない

呼び出し権限

Amazon Cognito サービスプリンシパルに、Lambda 関数を呼び出すための cognito-idp.amazonaws.com へのアクセス権を付与します。
コンソール画面からも追加できますが、AWS CLIでも追加できます。
Lambda>関数>[function name]>アクセス権限を追加
スクリーンショット 2023-10-12 11.01.17.png

  • AWS CLI
    aws lambda add-permission \
      --function-name <lambda_arn> \
      --statement-id "CognitoLambdaInvokeAccess" \
      --action lambda:InvokeFunction \
      --principal cognito-idp.amazonaws.com
    

Cognitoにトリガーを設定

ここは注意点あります。カスタムEメール送信者LambdaトリガーはコンソールやCloudFormationから作成できないので、AWS CLIを利用します。

# 既存の設定の確認
aws cognito-idp describe-user-pool --user-pool-id YOUR_USER_POOL_ID

# トリガー作成
aws cognito-idp update-user-pool \
  --userpool-id <userpool_id> \
  --lambda-config "CustomEmailSender={LambdaVersion=V1_0,LambdaArn= <lambda_arn> },KMSKeyID= <key_id>" \
  --auto-verified-attributes email

AWS ドキュメントに--auto-verified-attributes emailのオプションが必要だと書かれていませんが、実行すると[Cognitoが検証と確認のためにメッセージを自動的に送信することを許可]の値が[無効]となってしまい、メール送信自体できなくなります。そのオプションを忘れずにつけてください。

おまけ

トリガーだけ削除したい時、下記のコマンドで追加したトリガーをリセットします。

aws cognito-idp update-user-pool \
  --userpool-id <userpool_id> \
  --lambda-config "{}"

AWS Cognito APIでトリガー

トリガーするAPIは下記のAWSドキュメンに書いてますが、キャプチャーを貼ります。
スクリーンショット 2023-10-12 11.40.10.png

参考

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0