【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で環境名を取得する
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を設定します。
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用ヘルパーの情報が少なく、記載方法にとまどいましたのでどなたかの参考になれば幸いです。