[Amplify] @httpディレクティブでCognito Authorizer付きAPI Gatewayを Amplify Libraryから呼び出そうとすると"Template transformation yielded an empty response."エラーになる

Posted on November 14, 2020  -  1 min read

掲題の通り、Amplify の @http ディレクティブを使って AppSync から Cognito Authorizer を指定した API Gateway を Amplify Library から呼び出そうとすると “Template transformation yielded an empty response.” になりました。

AppSync ログを Cloudwatch Logs に出力し、原因を調べたところ、どうやら resolver の中で Unauthorized エラーになっているようでした。

unauthorized

AppSync の Authorizer に Cognito UserPool を指定する場合、Authorization ヘッダーの認証情報は API Gateway にも引き継がれるので問題ないかと思っていましたが、同じ Cognito UserPool を Authorizer に指定しているにも関わらず Unauthorized エラーになります。

原因としては、AppSync はaccess tokenを用いて認証しているのに対し、API Gateway はId Tokenを使用しているためでした。

architecture

Amplify Library で、AppSync のカスタムヘッダーに Id Token を指定すると解決しました。

Amplify.configure({
  API: {
    aws_appsync_authenticationType: 'AMAZON_COGNITO_USER_POOLS',
    aws_appsync_graphqlEndpoint:
      "https://xxxxxxxxxxxxxxxx.appsync-api.us-east-1.amazonaws.com/graphql",
    aws_appsync_region: "us-east-1",
    // Authorization HeaderにIdTokenを指定
    graphql_headers: async () => {
      const session = await Auth.currentSession();
      return {
        Authorization: session.getIdToken().getJwtToken(),
      };
    },
  },
  (snip..)

複数のマイクロサービスを一つの AppSync で IF を統一するなど、クライアントにバックエンドを意識させない仕組みとして@http ディレクティブは非常に有用だと思うので今後も積極的に活用していきたいと思います。