0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Amazon API GatewayでAPIキー利用者の情報をbackendに渡す

Last updated at Posted at 2023-07-30

以下ユースケースを実現する設定, 実装をする

ユースケース

外部のA社とB社にAmazon API Gateway(以下API Gateway)のREST APIを使用してAPIを公開している
認証方法はA社とB社それぞれにAPI Gatewayで発行したAPIキーを利用してもらう
backendでどの会社からのリクエストかを判定して認可処理をする

アーキテクチャ

image.png
Lambda Authorizerを使用する

設定手順

  1. backendを用意する
    今回はローカルで立てたexpressサーバーをngrokでpublicに公開する

    1. HTTPリクエストヘッダー"x-company"の値をそのままレスポンスするexpressサーバーを起動する
      node.js
      const express = require('express');
      const app = express();
      
      app.get('/', (req, res) => {
        res.send(req.headers['x-company']);
      });
      
      app.listen(80, () => { });
      
    2. ngrokを起動する
      ngrok http 80
      
  2. API Gateway REST APIを作成する

    1. 適当な設定値でREST APIを作成する
    2. 以下のパラメータでメソッドを作成する
      • 統合タイプ: HTTP
      • エンドポイント URL: <ngrokのURL>
        image.png
    3. [メソッドリクエスト]で[API キーの必要性]をtrueに設定する
  3. APIキーを作成する

    1. company Aとcompany B用のAPIキーを作成する
      IDはあとで使用する
      image.png
  4. Lambda Authorizerを作成する

    1. Node.jsでLambda関数を作成する
    2. 以下コードを入力する
      node.js
      import { APIGatewayClient, GetApiKeyCommand } from '@aws-sdk/client-api-gateway';
      
      export const handler = async function(event, context) {
          const client = new APIGatewayClient();
          
          // API GatewayにあるAPIキーの値を取得する
          const apiKeyCompanyA = (await client.send(new GetApiKeyCommand({apiKey: '<company AのAPIキーのID>', includeValue: true}))).value;
          const apiKeyCompanyB = (await client.send(new GetApiKeyCommand({apiKey: '<company BのAPIキーのID>', includeValue: true}))).value;
          
          // ヘッダーに付与されたAPIキーを取得
          const requestedApiKey = event.headers['x-api-key'];
          
          let xCompany = '';
          
          switch (requestedApiKey) {
            case apiKeyCompanyA:
              xCompany = 'companyA';
              break;
            case apiKeyCompanyB:
              xCompany = 'companyB';
              break;
          }
      
          let authResponse = {};
          authResponse.principalId = 'me';
          let policyDocument = {};
          policyDocument.Version = '2012-10-17';
          policyDocument.Statement = [];
          let statementOne = {};
          statementOne.Action = 'execute-api:Invoke';
          statementOne.Effect = 'Allow';
          statementOne.Resource = event.methodArn;
          policyDocument.Statement[0] = statementOne;
          authResponse.policyDocument = policyDocument;
          // どの会社かを記録
          authResponse.context = {
              'xCompany': xCompany,
          };
          
          return authResponse;
      }
      
    3. LambdaからAPIキーを取得するため、LambdaのIAMロールに"apigateway:GET"できるIAMポリシーを追加する
  5. REST APIにLambda Authorizerを設定し、Authorizerで設定した変数をbackendに渡す

    1. 以下のパラメータでLambda Authorizerを作成する
      • Lambda イベントペイロード: リクエスト
        image.png
    2. REST API -> [メソッドリクエスト] -> [認可] で作成したLambda Authorizerを設定する
      image.png
    3. REST API -> [統合リクエスト] -> [HTTP ヘッダー] で以下設定をする
      • 名前: x-company
      • マッピング元: context.authorizer.xCompany
        image.png
  6. REST APIをデプロイする

  7. REST APIと使用量プランとAPIキーを紐づける

動作確認

$ curl <REST APIのURL> -H "x-api-key: <company AのAPIキー>"    
companyA%                                                                                

$ curl <REST APIのURL> -H "x-api-key: <company BのAPIキー>"    
companyB%
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?