Open7

Cognitoのカスタム属性について

TAKAHASHI TaroTAKAHASHI Taro

Cognitoユーザープールにはカスタム属性を50個まで追加できる。

利用中のプラン(Free/Pro)やStripeのセッションIDはここに格納しようと思い、数日前からトライしたが挫折。供養代わりに途中までやったことを残しておく。→最終的に解決した。

Lambda上のPythonからboto3経由でカスタム属性を更新するのはできた。

    # ユーザープールのカスタム属性を更新
    cognito_cli.admin_update_user_attributes(
        UserPoolId=user_pool_id,
        Username=user_name,
        UserAttributes=[
            {
                'Name': 'custom:plan_type',
                'Value': 'FREE'
            }
        ]
    )
TAKAHASHI TaroTAKAHASHI Taro

Reactからカスタム属性を取得するにはAuthのuserAttributes()を使えばよさそう。

https://aws-amplify.github.io/amplify-js/api/classes/authclass.html#userattributes

Auth.userAttributes(user)

ところが実行すると以下のようなエラーが出る。

Client.js:145 Uncaught (in promise) NotAuthorizedException: Access Token does not have required scopes

しらべるとCognitoのOpenID Connect スコープにaws.cognito.signin.user.adminを追加してやる必要がありそう。

ところが追加してログインしてもやはり同じエラーが発生する。

TAKAHASHI TaroTAKAHASHI Taro

試しにGoogleのアイデンティティプロバイダー設定で「許可されたスコープ」を追加してみた。

そうしたら承認エラーでログインできなくなった。そりゃそうだ。GoogleがAWSのスコープを持っているわけがない。

Some requested scopes were invalid. {valid=[https://www.googleapis.com/auth/userinfo.profile, https://www.googleapis.com/auth/userinfo.email, openid], invalid=[aws.cognito.signin.user.admin]}

TAKAHASHI TaroTAKAHASHI Taro

設定を戻してログインはできるようになったが、これ以上できることが思いつかない。Google認証と組み合わせるとカスタム属性は使えないのだろうか。実装上はカスタム属性の代わりにDynamoDBに格納すればよいのだけれど、すごく負けた気分。くやしい。

TAKAHASHI TaroTAKAHASHI Taro

もうひとつできることがあったのを思い出した。Amplify.configure(awsExports)で使用しているawsExports.ts。この中にもスコープの設定があったのでは。

awsExports.ts
// Amplifyの設定
const awsExports = {
  Auth: {
    region: import.meta.env.VITE_REGION,
    userPoolId: import.meta.env.VITE_USER_POOL_ID,
    userPoolWebClientId: import.meta.env.VITE_USER_POOL_WEB_CLIENT_ID,
    oauth: {
      domain: import.meta.env.VITE_OAUTH_DOMAIN,
      scope: ['openid', 'aws.cognito.signin.user.admin'],
      redirectSignIn: import.meta.env.VITE_OAUTH_REDIRECT_SIGN_IN,
      redirectSignOut: import.meta.env.VITE_OAUTH_REDIRECT_SIGN_OUT,
      responseType: 'code',
    },
  },
};

export default awsExports;

上記のように修正してみた。