LoginSignup
1
0

Cognitoでログイン後Pollyを呼び出す

Last updated at Posted at 2024-03-08

AWSのCognitoの認証・認可関係でつまりに詰まったので、まとめます。

・やりたいこと:
サイトにログイン機能を実装し、ログインしたユーザーがAWS Pollyを呼び出してテキストを読み上げてほしい。

・前提:
amplify authでいい感じに実装してほしかったが、うまくいかなかったので、Cognitoの概念自体を学びなおしました。

1, Cognitoとは?

 ログイン機能を簡単に作ってくれます。もっと詳しく書くと、認証をつかさどるユーザープールと、認可をつかさどるidプールに分かれます。つまり、ユーザープールでユーザー名やパスワード、Eメールなどで本人確認を行い、そこで認証したユーザーに、idプールが適切なAWSサービスへのアクセス権限を与えてくれます。

2, ユーザープールの作成

 新規のユーザープールを作る際に、ユーザープールとWebアプリの紐づけを行います。amplifyで設定を更新後、アプリのログイン画面からユーザーが作成できることを確認します。
 ユーザーの中でも管理者と一般ユーザーというように、group分けして、idプールでgroupごとに与える権限を変えることも可能です。今回は無視。

3, idプールの作成

a, ユーザープールとidプールの紐づけ

 idプールの「ID プロバイダー」項目でユーザープールが紐づいていることを確認します。

b, 認証されたアクセスとゲストアクセスの権限設定

 ログイン後のユーザーには認証されたアクセス権限を、ログイン前のユーザーにはゲストアクセスの権限を与えます。必ず2種類設定しないと、amplifyで使えなかったのに気づかず、ずっとはまっていました。
 それぞれIAMロールを作成するのですが、IAMロールにも「許可ポリシー」と「信頼ポリシー」という2つの種類があり、適切な設定が必要です。

・「許可ポリシー」とは?
 その名の通り、AWSサービスへの許可リストのことです。今回はPollyを呼び出せる権限をつけたいので、ゲストユーザーにはCognito identity、ログイン後のユーザーには雑に「AmazonCognitoUnAuthedIdentitiesSessionPolicy」をつけます。(あくまでテスト段階なので、後ほど適切な権限に切り替えます)

・「信頼ポリシー」とは?
 雑に言うと、「誰に対して」先ほどの許可ポリシーを付与するのか?という宣言です。今回はCognitoのidプール自体につけるので、以下のようなjsonにします。

信頼されたエンティティ
{
  "Version": "2012-10-17",
  "Statement": [{
    "Effect": "Allow",
    "Principal": {
      "Federated": "cognito-identity.amazonaws.com" 
      # 「誰に」許可を与えるか宣言
    },
    "Action": [
      "sts:AssumeRoleWithWebIdentity",
      "sts:TagSession"  
    ],
    "Condition": {
      "StringEquals": {
        "cognito-identity.amazonaws.com:aud": {自分のidプールのid}
      },
      "ForAnyValue:StringLike": {
        "cognito-identity.amazonaws.com:amr": "authenticated"
        # ログイン後のユーザーのIAMの場合、"authenticated",
         ゲストユーザーのIAMの場合、"unauthenticated"
      }
    }
  }]
}

c, ユーザーグループのgroupごとに適切なIAMロールを付与。

今回は対象外のため、割愛

4, 確認

 Webアプリでログイン後、Pollyを呼び出せることを確認します。
なんとかできました。AWSサービスは独自の造語が多く、翻訳が大変でした。

5, おまけ

 Cognitoの認証・認可機能を使って、ローカルからlambdaなどAWSサービスを呼びます。

  const idToken = (await fetchAuthSession()).tokens?.idToken ?? "";

 credentials作成に必要なidentity idを呼び出します。cognitoにはidがいろいろあってややこしいのではまりましたが、必要なのはidプールのidentity idでした。amplify公式ドキュメントにある上記のコードで取得可能です。公式↓
https://docs.amplify.aws/react/build-a-backend/auth/manage-user-session/

  const userPoolUrl 
          = 'cognito-idp.' 
          + {cognitoのリージョン} 
          + '.amazonaws.com/' 
          + {ユーザープールのid}

ユーザープールのurlを作ります。

  const credentials = fromCognitoIdentityPool({
        identityPoolId: {idプールのidentity id},
    logins: { // 認証情報。ユーザープールのほか、OAUTH認証もこちらで使用
      [userPoolUrl]: idToken.toString(),
    },
    clientConfig: { region: {クライエントのawsリージョン} },
  });

上記で作ったidTokenとuserPoolUrlを使って、credentialsを作ります。

// ローカルで各サービスのクライエントを用意
const lambdaClient = new LambdaClient({ 
   region: {region}, // リージョン
   credentials // 上記で作ったcredentials。
})

Clientができました。AWSサービスを呼び出す準備が整いました。
ちなみにcredentialsを省略してClientを作った場合、idプールのゲストユーザーの権限で各サービスを呼び出してます。

1
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
1
0