1
Help us understand the problem. What are the problem?
Organization

[Amplify]APIGatewayのAuthorizerにCognitoを指定する

概要

AmplifyでOverride機能を利用してAPIGatewayのAuthorizerにCognitoを指定する方法をご紹介します。

課題

2022/3/10現在、Amplify CLIでは、APIGatewayのAuthorizerにIAMしか利用できません。AWSのコンソールからCognitoを指定したとしても更新した際にテンプレートで上書きされてしまい、設定したAuthorizerの情報が消えてしまいます。
そのため、Override機能を利用してAPIのCFnテンプレートを修正する必要があります。

手順

APIGateway・Cognitoのoverride.ts作成

CLIで以下のコマンドを実行し、override.tsを作成します

amplify override auth
amplify override api

override.tsの編集

Authでは、CognitoユーザープールのIDをエクスポートします。
エクスポート名は重複が許されないため、環境名を取得してユニークにしています。しかし、デフォルトではバグで取得できないため迂回しています。詳細は以下の記事をご覧ください。
Amplifyのoverride.tsで環境名を取得する

amplify/backend/auth/[Auth名]/override.ts
import { AmplifyAuthCognitoStackTemplate } from '@aws-amplify/cli-extensibility-helper';

export function override(resources: AmplifyAuthCognitoStackTemplate) {
  // override.tsでenv名を参照することはできない(バグ)。そのためamplify-metaからenv名を取得している
  // https://github.com/aws-amplify/amplify-cli/issues/9063
  const amplify_meta_json = require('amplify-meta.json')
  const env_name = amplify_meta_json.providers.awscloudformation.StackName.split("-").slice(-2, -1).pop()
  const export_user_pool_id = {
      description: "cognito user pool id",
      value: resources.userPool.ref,
      exportName: `exportUserPoolId-${env_name}`
  }
  resources.addCfnOutput(export_user_pool_id, "AuthCognitoUserPoolId")
}

AuthでエクスポートしたユーザープールIDを利用してAuthorizerを設定します。

amplify/backend/api/[API名]/override.ts
import { AmplifyApiRestResourceStackTemplate } from '@aws-amplify/cli-extensibility-helper';

export function override(resources: AmplifyApiRestResourceStackTemplate) {
  const amplify_meta_json = require('amplify-meta.json')
  const env_name = amplify_meta_json.providers.awscloudformation.StackName.split("-").slice(-2, -1).pop()
  resources.restApi.body = {
    ...resources.restApi.body,
    "securityDefinitions": {
      "sigv4": {
        "type": "apiKey",
        "name": "Authorization",
        "in": "header",
        "x-amazon-apigateway-authtype": "awsSigv4"
      },
      "Cognito": {
        "type": "apiKey",
        "name": "Authorization",
        "in": "header",
        "x-amazon-apigateway-authtype": "cognito_user_pools",
        "x-amazon-apigateway-authorizer": {
          "type": "cognito_user_pools",
          "providerARNs": [
            {
              "Fn::Join": [
                "",
                [
                  "arn:aws:cognito-idp:",
                  {
                    "Ref": "AWS::Region"
                  },
                  ":",
                  {
                    "Ref": "AWS::AccountId"
                  },
                  ":userpool/",
                  {
                    "Fn::ImportValue": `exportUserPoolId-${env_name}`
                  }
                ]
              ]
            }
          ]
        }
      }
    },
  }

  //Authorizerはリソースの各メソッドに設定する必要がある
  let paths = resources.restApi.body.paths
  Object.keys(paths).forEach((key) => {
    let path = paths[key]["x-amazon-apigateway-any-method"]
    path.parameters = [
      ...path.parameters,
      {
        name: "Authorization",
        in: "header",
        required: false,
        type: "string"
      }
    ]
    path.security = [
      {
        "Cognito": []
      }
    ]
  });
}

まとめ

上記設定でAuthorizerにCognitoを使用することができます。
AmplifyのOverride用ヘルパーの情報が少なく、記載方法にとまどいましたのでどなたかの参考になれば幸いです。

Register as a new user and use Qiita more conveniently

  1. You can follow users and tags
  2. you can stock useful information
  3. You can make editorial suggestions for articles
What you can do with signing up
1
Help us understand the problem. What are the problem?