Amplify x Next.js の API Routes で AWSクレデンシャル情報を取得してみた

2022.09.08

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

こんにちは!DA(データアナリティクス)事業本部 サービスソリューション部の大高です。

Amplify UI の Authenticator で認証をかけたアプリで、 Next.js の API Routes を利用しているときに「あー、AWSのクレデンシャル情報を利用したいなー!」と思うことはありませんか?私はあります。

例えば、API Routes で aws-sdk を利用して DynamoDB にアクセスするようなケースでは、DynamoDBClientcredentialsを設定してあげる必要があるので、AWSのクレデンシャル情報が必要になってきます。

今回はこのAWSクレデンシャル情報の取得について書いていきたいと思います。

前提条件

今回試した環境は以下のとおりです。なお、利用している Amplify Hosting の関係でちょっとバージョンが古いです。

  • next
    • ^11.1.4
  • aws-amplify
    • ^4.3.22

また、ログイン時に利用するCognitoの「ユーザープール」の「ユーザー」は、「グループ」に所属しており、「グループ」に対しては「IAMロール」を設定済みです。

こうすることで、実際に取得したAWSクレデンシャル情報を利用して DynamoDB などにアクセスする際には、この「IAMロール」の権限に従ってアクセス制御がされることになります。

具体的には下記のドキュメントが参考になるかと思います。

API Routes で Amplify のクレデンシャル情報を取得してみる

ということで、以下がサンプルのコードになります。

some-api.ts

import type { Credentials } from '@aws-sdk/types'
import { Amplify, withSSRContext } from 'aws-amplify'

import type { NextApiRequest, NextApiResponse } from 'next'

import { DynamoDBClient } from '@aws-sdk/client-dynamodb'

Amplify.configure({
  Auth: {
    region: process.env.NEXT_PUBLIC_AWS_REGION,
    userPoolId: process.env.NEXT_PUBLIC_COGNITO_USER_POOL_ID,
    identityPoolId: process.env.NEXT_PUBLIC_COGNITO_IDENTITY_POOL_ID,
    identityPoolRegion: process.env.NEXT_PUBLIC_COGNITO_IDENTITY_POOL_REGION,
    userPoolWebClientId: process.env.NEXT_PUBLIC_COGNITO_USER_POOL_WEB_CLIENT_ID,
  },
  ssr: true,
})

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
  const SSR = withSSRContext({ req: req })
  const credentials: Credentials = await SSR.API.Auth.currentCredentials()
  const client = new DynamoDBClient({
    credentials: credentials,
    region: 'ap-northeast-1',
  })

  // DynamoDBに対する操作など
  // const input: XXXXXCommandInput = ; // 必要なCommandInputを定義
  // const command: XXXXXCommand = new XXXXXCommand(input) // Commandを定義
  // const response: XXXXXCommandOutput = await client.send(command) // Command呼び出し

  // 結果などを返却
  // res.json(response)
}

まずは、サーバーサイドでの処理になるのでAmplify.configureを利用して、Amplifyの設定をしています。

なお、これについては、最新のNext.jsが利用できる場合には不要かもしれません。以下のIssueをご参照ください。

次にメインとなるクレデンシャル情報取得の箇所ですが、withSSRContextを利用することでクライアントサイドからCookieとして渡されたクレデンシャル情報を利用できるようにして、SSR.API.Auth.currentCredentials()で実際に情報を取得しています。

あとは、適宜DynamoDBClientなど、利用したいクライアントにcredentials情報を設定して、コマンドを発行するだけです。

クライアントサイドでは単純にAuth.currentCredentials()だけでクレデンシャル情報が取得できますが、このあたりが少しサーバーサイドになるAPI Routesでは変わってきますね。

ドキュメントとしては、以下が参考になります。

まとめ

以上、Amplify x Next.js の API Routes で AWSクレデンシャル情報を取得してみました。

AWSリソースへのアクセスをサーバーサイド側で処理したい場合などに、このクレデンシャル情報の取得方法が役立つかなと思います。

どなたかのお役に立てば幸いです。それでは!