前回、 Amplify Gen2のLINEログイン時にLINEのIDトークンを取得、検証できた。
今回はIDトークンの検証結果から、LINEユーザーIDを取得し、保存するまでをメモ。
環境
前々回・前回同様、 @aws-amplify/backend v1.0.4, @aws-amplify/backend-cli (ampx) v1.2.1。
実装
前回、preSignUpトリガーにてIDトークンのverifyを行った。ただ、どうやらpreSignUp内ではCognitoの属性の変更ができないらしい。
今回はpostConfirmationにて同様の処理を行い、Cognitoの属性を更新することでLINEユーザーIDを保存する。
Googleログイン時に、postConfirmationトリガーは作成済みのため、そこに追記する。
トリガーへのアクセス許可の追加
amplify/auth/resource.ts にて、postConfirmationへアクセス許可を追加する。もともと addUserToGroup を設定していたが、今回は updateUserAttributes, deleteUserAttributes の2つを追加。
export const auth = defineAuth({ // 中略 // 前回追加しておいた、custom:line_user_idをユーザーID保存に用いる userAttributes: { 'custom:line_id_token': { dataType: 'String', maxLen: 2048 }, 'custom:line_user_id': { dataType: 'String', maxLen: 33 }, }, triggers: { preSignUp, postConfirmation }, access: allow => [ allow .resource(postConfirmation) // updateUserAttributes, deleteUserAttributesを追加 .to(['addUserToGroup', 'updateUserAttributes', 'deleteUserAttributes']), ], })
postConfirmationトリガーの実装
まずはpreSignUpと同様、 amplify/auth/postConfirmation/resource.ts でLINEチャネルIDを環境変数として参照できるようにしておく。
export const postConfirmation = defineFunction({ environment: { LINE_CHANNEL_ID: secret('LINE_CHANNEL_ID'), }, })
続いて、 amplify/auth/postConfirmation/handler.ts を実装。IDトークンの検証はpreSignUpと同じだが、検証結果として取得したユーザーIDをCognitoのカスタム属性として保存し、あわせてIDトークンを保存した属性を削除している。
import { AdminDeleteUserAttributesCommand, AdminUpdateUserAttributesCommand, CognitoIdentityProviderClient, } from '@aws-sdk/client-cognito-identity-provider' const cognitoClient = new CognitoIdentityProviderClient() export const handler: PostConfirmationTriggerHandler = async event => { const { userName, userPoolId, request: { userAttributes }, } = event // IDトークンからLINEユーザーIDの取得は前回と同じため省略 const { sub: lineUserId } = await verifyLineIdToken(userAttributes['custom:line_id_token']) const commonCommandInput = { UserPoolId: userPoolId, Username: userName, } // LINEユーザーIDの保存 const updateCommand = new AdminUpdateUserAttributesCommand({ ...commonCommandInput, UserAttributes: [{ Name: 'custom:line_user_id', Value: lineUserId }], }) await cognitoClient.send(updateCommand) // 不要となったIDトークンの削除 const deleteCommand = new AdminDeleteUserAttributesCommand({ ...commonCommandInput, UserAttributeNames: ['custom:line_id_token'], }) await cognitoClient.send(deleteCommand) return event }
これでLINEユーザーIDが custom:line_user_id に保存される。その値を用いて、LINE公式アカウントのユーザーとのマッピングが可能となった。
振り返り
preSignUpでCognitoの属性の更新ができれば、そこで完結できて楽だったんだが。
ひとまずトリガーを分けて対応できたので、良しとしておこう。