AWS - API Gateway

提供: MochiuWiki : SUSE, EC, PCB

2025年12月11日 (木) 16:00時点におけるWiki (トーク | 投稿記録)による版 (認証方法)
(差分) ← 古い版 | 最新版 (差分) | 新しい版 → (差分)

概要

AWS API Gatewayは、AWSが提供するフルマネージド型のAPIサービスである。
開発者がRESTful APIやWebSocket APIを簡単に作成、公開、管理、保護できる環境を提供する。

主な特徴を以下に示す。

  • フルマネージド
    サーバ管理やスケーリングの自動化
  • 複数のAPIタイプ
    REST API、HTTP API、WebSocket APIをサポート
  • バックエンド統合
    Lambda、EC2、DynamoDB、他のAWSサービスとの統合
  • セキュリティ機能
    IAM認証、Cognito認証、APIキー、カスタムオーソライザー
  • トラフィック管理
    スロットリング、キャッシング、リクエスト検証
  • モニタリング
    CloudWatchとの統合による詳細なメトリクス


AWS API Gatewayが提供する3つのAPIタイプを以下に示す。

  • REST API
    従来型のRESTful API、豊富な機能を提供
    API管理機能、リクエスト変換、レスポンス変換をサポート
  • HTTP API
    シンプルで低コストなAPI、REST APIのサブセット
    基本的な機能に特化し、最大70%のコスト削減が可能
  • WebSocket API
    双方向通信をサポート、リアルタイムアプリケーション向け
    チャット、ゲーム、金融取引アプリケーション等に適する


AWS API Gatewayは永続的な無料利用枠を提供しており、個人利用や小規模なアプリケーションであれば無料枠内で運用できることが多い。


認証方法

AWS Lambdaを使用するアプリケーションを開発する場合、認証戦略を考慮する必要がある。

  1. Cognito認証 (推奨)
    不特定多数向けのクライアントアプリケーション向け。
    ユーザごとに認証・認可を行う場合に最適である。
    ユーザ登録、ログイン、トークン管理等を自動で処理する。
    特に、ユーザごとにデータを分離する場合、または、細かいアクセス制御が必要な場合に向いている。

  2. API Keyによる認証 (最も簡単)
    不特定多数向けのクライアントアプリケーション向け。
    API Gatewayで発行したAPIキーをクライアントアプリケーションに埋め込む方法である。
    ただし、クライアントアプリケーションからキーを抽出される可能性があるため、使用量の制限や課金が必要ない公開APIに適している。

  3. IAM認証
    企業内や信頼できるクライアント向け。
    AWS認証情報を使用するため、不特定多数向けには推奨されない。



API Gatewayの無料枠について

無料枠の内容

  • HTTP API
    月100万回のAPIコールまで無料 (永続的)
    この無料枠は永続的に利用可能である。
  • REST API
    月100万回のAPIコールまで無料 (最初の12ヶ月間)
    12ヶ月後は課金対象となる
  • WebSocket API
    月100万メッセージまで無料 (最初の12ヶ月間)
    月75万接続分まで無料 (最初の12ヶ月間)


※注意

  • HTTP APIの無料枠のみが永続的である。
  • REST APIとWebSocket APIの無料枠は最初の12ヶ月間のみである。
  • データ転送料金は別途発生する。
  • キャッシングを有効にした場合は追加料金が発生する。


料金体系

無料枠を超えた場合の料金 (東京リージョンの例)

  • HTTP API
    • APIコール : $1.17 / 100万リクエスト
    • REST APIと比較して約70%のコスト削減

  • REST API
    • APIコール : $4.25 / 100万リクエスト
    • キャッシング : $0.020 / 時間 (0.5GBキャッシュの場合)

  • WebSocket API
    • メッセージ : $1.17 / 100万メッセージ
    • 接続時間 : $0.315 / 100万接続分

  • データ転送
    • アウトバウンド : 最初の10[TB]まで $0.114 / GB
    • インバウンド : 無料



API Gatewayの停止

AWS API Gatewayには従来的な意味での停止という概念がない。
Lambda同様、サーバーレスサービスであり、リクエストが来た時のみ課金されるためである。

コストを抑える方法

使用していない場合のコストを抑えるには、以下に示す選択肢がある。

1. ステージの削除
  • デプロイされたステージを削除する。
  • ステージが存在しなければAPIにアクセスできない。
  • API自体は残しておくことができる。


2. APIの削除
  • 完全に使用しない場合はAPI自体を削除する。
  • 必要に応じて再作成可能である。
  • CloudFormationやTerraformでインフラストラクチャをコード化しておくことを推奨する。


3. HTTP APIの使用
  • 新規作成の場合は、HTTP APIを優先的に検討する。
  • REST APIと比較して最大70%のコスト削減が可能である。
  • 必要な機能がHTTP APIでカバーできる場合は、HTTP APIを選択する。


4. キャッシングの無効化
  • キャッシング機能は使用していなくても課金される。
  • 必要がなければキャッシングを無効化する。


コスト構造について

リクエストがない場合

  • API自体の維持費は発生しない (無料)
  • キャッシングを有効にしている場合のみ時間課金が発生する
  • 基本的にコストは0円またはほぼ0円


リクエストがある場合

  • リクエスト数に基づいて課金される。
  • 例 : HTTP API、月10万リクエストの場合
    10万リクエスト = 無料枠内 (100万まで無料)
    コスト : $0
  • 例 : REST API、月200万リクエストの場合 (12ヶ月後)
    200万リクエスト × $4.25 / 100万 = $8.50/月


コストを下げる方法

  • HTTP APIの活用
    新規APIはHTTP APIを優先的に検討する。
    REST APIからHTTP APIへの移行を検討する。
  • キャッシングの最適化
    必要な場合のみキャッシングを有効化する。
    キャッシュサイズを適切に設定する。
  • リクエストの削減
    バッチ処理やWebSocketの活用を検討する。
    クライアント側でのキャッシングを実装する。
  • リージョンの選択
    データ転送コストを考慮してリージョンを選択する。


完全に無料にするには、HTTP APIを使用し、月100万リクエスト以内に抑えること。


HTTP APIの作成

HTTP APIはREST APIよりもシンプルで低コストである。基本的なAPIであればHTTP APIの使用を推奨する。

マネジメントコンソールでの作成

  1. API Gatewayコンソールで [APIを作成] を選択する。
  2. HTTP API の [構築] を選択する。
  3. 統合を追加する。(オプション)
    • Lambda
      Lambda関数を選択
    • HTTPエンドポイント
      既存のエンドポイントを指定
    • 後で追加することも可能
  4. API名を入力する。
    例 : MyHttpAPI
  5. [次へ]を選択する。


ルートの設定

  1. HTTPメソッドを選択する。
    GET、POST、PUT、DELETE、PATCH、ANY 等
  2. リソースパスを入力する。
    例 : /users、/items/{id} 等
  3. 統合ターゲットを選択する。
    先ほど追加したLambda関数等
  4. 追加のルートを設定する場合は [ルートを追加] を選択する。
  5. [次へ]を選択する。


ステージの定義

  1. ステージ名を入力する。
    例 : $default (デフォルト)、dev、prod等
  2. 自動デプロイを有効化する。(推奨)
    変更が自動的にデプロイされる。
  3. [次へ]を選択する。


確認と作成

  1. 設定内容を確認する。
  2. [作成]を選択する。


作成が完了すると、APIのURLが表示される。

https://{api-id}.execute-api.ap-northeast-1.amazonaws.com/{resource}


HTTP APIではステージ名がURLに含まれない場合がある。($defaultステージの場合)


REST APIの作成

マネジメントコンソールでの作成

  1. AWSマネジメントコンソールにログインする。
  2. リージョンを選択する。
    東京リージョン : ap-northeast-1
  3. 検索バーに "API Gateway" と入力して選択する。
  4. [APIを作成]を選択する。


APIタイプの選択

  1. APIタイプを選択する。
    • REST API
      豊富な機能を持つ従来型のRESTful API
    • HTTP API
      シンプルで低コストなAPI (推奨)
    • WebSocket API
      双方向通信が必要な場合
    • REST API (Private)
      VPC内からのみアクセス可能なAPI
  2. [構築]を選択する。


REST APIの設定

  1. プロトコルを選択する。
    REST を選択
  2. 新しいAPIを作成する。
    • 新しいAPI
      新規にAPIを作成
    • サンプルAPIのクローン
      Petstore APIのサンプルを使用
    • OpenAPI 3.0からインポート
      既存のOpenAPI定義をインポート
  3. API名を入力する。
    例 : MyRestAPI
  4. 説明を入力する。(オプション)
    例 : 個人プロジェクト用のREST API
  5. エンドポイントタイプを選択する。
    • リージョン
      単一リージョンでの展開 (推奨)
    • エッジ最適化
      CloudFrontを使用したグローバル配信
    • プライベート
      VPC内からのみアクセス可能
  6. [APIの作成]を選択する。


リソースとメソッドの作成

  • リソースの作成
    1. [リソースを作成]を選択する。
    2. リソース名を入力する。
      例 : users
    3. リソースパスを確認する。
      自動的に /users が設定される
    4. [リソースの作成]を選択する。

  • メソッドの作成
    1. 作成したリソース (例 : /users) を選択する。
    2. [メソッドを作成]を選択する。
    3. HTTPメソッドを選択する。
      GET、POST、PUT、DELETE、PATCH等
    4. 統合タイプを選択する。
      • Lambda関数
        Lambda関数と統合 (推奨)
      • HTTPエンドポイント
        既存のHTTPエンドポイントにプロキシ
      • Mock
        テスト用のモックレスポンス
      • AWSサービス
        DynamoDB、S3等と直接統合
    5. Lambda関数を選択する場合
      • Lambda関数名を入力する
      • Lambda プロキシ統合を有効化する (推奨)
    6. [保存]を選択する。
    7. Lambda関数の実行許可を求められた場合は [OK] を選択する。


APIのデプロイ

  1. [アクション] - [APIのデプロイ]を選択する。
  2. デプロイされるステージを選択する。
    • [新しいステージ]
      新しいステージを作成
    • 既存のステージ
      既存のステージにデプロイ
  3. ステージ名を入力する。
    例 : dev、prod、test 等
  4. ステージの説明を入力する。(オプション)
  5. [デプロイ]を選択する。


デプロイが完了すると、APIのURLが表示される。

https://{api-id}.execute-api.ap-northeast-1.amazonaws.com/{stage-name}/{resource}


# 例 :
https://abc123def4.execute-api.ap-northeast-1.amazonaws.com/dev/users



Lambda統合の設定

API GatewayとLambda関数を統合する時の設定について示す。

Lambda プロキシ統合

Lambda プロキシ統合を使用すると、APIリクエストの詳細情報がLambda関数に渡される。

  • Lambda関数で受け取るイベントの構造
 {
   "httpMethod": "GET",
   "path": "/users",
   "queryStringParameters": {
     "id": "123"
   },
   "headers": {
     "Content-Type": "application/json"
   },
   "body": null,
   "isBase64Encoded": false
 }


  • Lambda関数のレスポンス形式
 def lambda_handler(event, context):
    # リクエスト情報の取得
    http_method = event.get('httpMethod')
    path = event.get('path')
    query_params = event.get('queryStringParameters', {})
 
    # レスポンスの作成
    return {
       'statusCode': 200,
       'headers': {
          'Content-Type': 'application/json',
          'Access-Control-Allow-Origin': '*'  # CORS対応
       },
       'body': json.dumps({
          'message': 'Success',
          'data': {'id': '123', 'name': '山田太郎'}
       })
    }


CORSの設定

クロスオリジンリクエストを許可するには、CORSを設定する必要がある。

  • HTTP APIでのCORS設定
    1. APIを選択する。
    2. [CORS]を選択する。
    3. [設定]を選択する。
    4. アクセスコントロールの設定を行う。
      • Access-Control-Allow-Origin
        例 : * (すべて許可) または https://example.com
      • Access-Control-Allow-Methods
        例 : GET, POST, PUT, DELETE
      • Access-Control-Allow-Headers
        例 : Content-Type, Authorization
      • Access-Control-Max-Age
        例 : 300 (秒)
    5. [保存]を選択する。

  • REST APIでのCORS設定
    1. リソースを選択する。
    2. [アクション] - [CORSの有効化] を選択する。
    3. 設定を確認する。
    4. [CORSを有効にして既存のCORSヘッダーを置換] を選択する。
    5. OPTIONSメソッドが自動的に作成される。



Linux PCからのアクセス設定

AWS CLIのインストール

Lambda編で説明した方法と同じ手順でAWS CLIをインストールする。

方法1 : pip経由 (推奨)

Python3をインストールする。

sudo apt update
sudo apt install python3 python3-pip -y


AWS CLIをインストールする。

pip3 install awscli --user


正常にインストールされているかどうかを確認する。

aws --version


方法2 : 公式インストーラ

AWS CLIをダウンロードおよびインストールする。

curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
unzip awscliv2.zip
sudo ./aws/install


正常にインストールされているかどうかを確認する。

aws --version


AWS CLIの設定

設定コマンドを実行する。

aws configure


以下に示すものを順番に入力する。

  • AWS Access Key ID
    作成したアクセスキーID
  • AWS Secret Access Key
    シークレットアクセスキー
  • Default region name
    例 : ap-northeast-1 (東京リージョン)
  • Default output format
    json (推奨)


接続テスト

API一覧を取得する。

aws apigateway get-rest-apis


HTTP APIの一覧を取得する。

aws apigatewayv2 get-apis


特定のAPIの情報を取得する。

aws apigateway get-rest-api --rest-api-id {api-id}



API Gatewayの基本操作 (CLI)

APIの一覧取得

 # REST APIの一覧
 aws apigateway get-rest-apis
 
 # HTTP APIの一覧
 aws apigatewayv2 get-apis


リソースの一覧取得

 # REST APIのリソース一覧
 aws apigateway get-resources \
     --rest-api-id abc123def4


APIのデプロイ

 # REST APIのデプロイ
 aws apigateway create-deployment \
     --rest-api-id abc123def4 \
     --stage-name dev \
     --description "初回デプロイ"


ステージの作成

 # 新しいステージの作成
 aws apigateway create-stage \
     --rest-api-id abc123def4 \
     --stage-name prod \
     --deployment-id xyz789


APIのテスト

 # curlでAPIをテスト
 curl https://abc123def4.execute-api.ap-northeast-1.amazonaws.com/dev/users
 
 # POSTリクエストの例
 curl -X POST \
    https://abc123def4.execute-api.ap-northeast-1.amazonaws.com/dev/users \
    -H "Content-Type: application/json" \
    -d '{"name": "山田太郎", "email": "yamada@example.com"}'
 
 # 認証ヘッダを含むリクエスト
 curl https://abc123def4.execute-api.ap-northeast-1.amazonaws.com/dev/users \
    -H "Authorization: Bearer YOUR_TOKEN_HERE"


ログの確認

 # CloudWatch Logsのログストリーム確認
 aws logs describe-log-streams \
     --log-group-name API-Gateway-Execution-Logs_abc123def4/dev \
     --order-by LastEventTime \
     --descending


APIの削除

 # REST APIの削除
 aws apigateway delete-rest-api \
     --rest-api-id abc123def4
 
 # HTTP APIの削除
 aws apigatewayv2 delete-api \
     --api-id xyz789ghi0



Python SDK (boto3) の使用

以下の例では、Pythonを使用してAWS API Gatewayを操作している。

まず、boto3とrequestsをインストールする。

pip3 install boto3 requests --user


 # apigateway_example.py
 
 import boto3
 import json
 
 # API Gatewayクライアントの作成
 apigateway = boto3.client('apigateway', region_name='ap-northeast-1')
 
 # REST APIの一覧取得
 def list_rest_apis():
    response = apigateway.get_rest_apis()
 
    for api in response['items']:
       print(f"API名: {api['name']}")
       print(f"  ID: {api['id']}")
       print(f"  作成日: {api['createdDate']}")
       print()
 
 # REST APIの作成
 def create_rest_api():
    response = apigateway.create_rest_api(
       name='MyNewAPI',
       description='Python SDKで作成したAPI',
       endpointConfiguration={
          'types': ['REGIONAL']
       }
    )
 
    api_id = response['id']
    print(f"API作成成功: {api_id}")
    return api_id
 
 # リソースの取得
 def get_resources(api_id):
    response = apigateway.get_resources(
       restApiId=api_id
    )
 
    return response['items']
 
 # リソースの作成
 def create_resource(api_id, parent_id, path_part):
    response = apigateway.create_resource(
       restApiId=api_id,
       parentId=parent_id,
       pathPart=path_part
    )
 
    resource_id = response['id']
    print(f"リソース作成成功: /{path_part} (ID: {resource_id})")
    return resource_id
 
 # メソッドの作成
 def create_method(api_id, resource_id, http_method, lambda_function_arn):
    # メソッドの作成
    apigateway.put_method(
       restApiId=api_id,
       resourceId=resource_id,
       httpMethod=http_method,
       authorizationType='NONE'
    )
 
    # Lambda統合の設定
    region = 'ap-northeast-1'
    uri = f'arn:aws:apigateway:{region}:lambda:path/2015-03-31/functions/{lambda_function_arn}/invocations'
    
    apigateway.put_integration(
       restApiId=api_id,
       resourceId=resource_id,
       httpMethod=http_method,
       type='AWS_PROXY',
       integrationHttpMethod='POST',
       uri=uri
    )
 
    print(f"メソッド作成成功: {http_method}")
 
 # デプロイの作成
 def deploy_api(api_id, stage_name):
    response = apigateway.create_deployment(
       restApiId=api_id,
       stageName=stage_name,
       description='自動デプロイ'
    )
 
    deployment_id = response['id']
    print(f"デプロイ成功: {deployment_id}")
    print(f"APIエンドポイント: https://{api_id}.execute-api.ap-northeast-1.amazonaws.com/{stage_name}")
 
 # ステージ設定の更新
 def update_stage_settings(api_id, stage_name):
    # ログ記録を有効化
    apigateway.update_stage(
       restApiId=api_id,
       stageName=stage_name,
       patchOperations=[
          {
             'op': 'replace',
             'path': '/*/*/logging/loglevel',
             'value': 'INFO'
          },
          {
             'op': 'replace',
             'path': '/*/*/logging/dataTrace',
             'value': 'true'
          },
          {
             'op': 'replace',
             'path': '/*/*/metrics/enabled',
             'value': 'true'
          }
       ]
    )
 
    print("ステージ設定更新完了")
 
 # APIの削除
 def delete_rest_api(api_id):
    apigateway.delete_rest_api(
       restApiId=api_id
    )
 
    print(f"API削除完了: {api_id}")
 
 # メイン処理
 if __name__ == '__main__':
    list_rest_apis()
 
    # 新しいAPIを作成する場合
    # api_id = create_rest_api()
    # resources = get_resources(api_id)
    # root_id = resources[0]['id']  # ルートリソース
    # resource_id = create_resource(api_id, root_id, 'users')
    # create_method(api_id, resource_id, 'GET', 'arn:aws:lambda:...')
    # deploy_api(api_id, 'dev')


# 実行方法
python3 apigateway_example.py


HTTP APIの操作

HTTP APIは異なるクライアント (apigatewayv2) を使用する。

 # http_api_example.py
 
 import boto3
 
 # HTTP API用のクライアント
 apigatewayv2 = boto3.client('apigatewayv2', region_name='ap-northeast-1')
 
 # HTTP APIの作成
 def create_http_api():
    response = apigatewayv2.create_api(
       Name='MyHttpAPI',
       ProtocolType='HTTP',
       Description='HTTP APIの例',
       CorsConfiguration={
          'AllowOrigins': ['*'],
          'AllowMethods': ['GET', 'POST', 'PUT', 'DELETE'],
          'AllowHeaders': ['Content-Type', 'Authorization']
       }
    )
 
    api_id = response['ApiId']
    print(f"HTTP API作成成功: {api_id}")
    return api_id
 
 # HTTP APIの一覧取得
 def list_http_apis():
    response = apigatewayv2.get_apis()
 
    for api in response['Items']:
       print(f"API名: {api['Name']}")
       print(f"  ID: {api['ApiId']}")
       print(f"  エンドポイント: {api['ApiEndpoint']}")
       print()
 
 # Lambda統合の作成
 def create_integration(api_id, lambda_function_arn):
    response = apigatewayv2.create_integration(
       ApiId=api_id,
       IntegrationType='AWS_PROXY',
       IntegrationUri=lambda_function_arn,
       PayloadFormatVersion='2.0'
    )
 
    integration_id = response['IntegrationId']
    print(f"統合作成成功: {integration_id}")
    return integration_id
 
 # ルートの作成
 def create_route(api_id, integration_id, route_key):
    response = apigatewayv2.create_route(
       ApiId=api_id,
       RouteKey=route_key,  # 例: 'GET /users', 'POST /items'
       Target=f'integrations/{integration_id}'
    )
 
    route_id = response['RouteId']
    print(f"ルート作成成功: {route_key}")
    return route_id
 
 # ステージの作成
 def create_stage(api_id, stage_name):
    response = apigatewayv2.create_stage(
       ApiId=api_id,
       StageName=stage_name,
       AutoDeploy=True
    )
 
    print(f"ステージ作成成功: {stage_name}")
 
 if __name__ == '__main__':
    list_http_apis()


APIへのリクエスト送信

作成したAPIにリクエストを送信する例を以下に示す。

 # api_request_example.py
 
 import requests
 import json
 
 # APIエンドポイント
 API_ENDPOINT = 'https://abc123def4.execute-api.ap-northeast-1.amazonaws.com/dev'
 
 # GETリクエストの例
 def get_users():
    url = f'{API_ENDPOINT}/users'
 
    response = requests.get(url)
 
    print(f"ステータスコード: {response.status_code}")
    print(f"レスポンス: {response.json()}")
 
 # POSTリクエストの例
 def create_user():
    url = f'{API_ENDPOINT}/users'
 
    data = {
       'name': '山田太郎',
       'email': 'yamada@example.com',
       'age': 30
    }
 
    headers = {
       'Content-Type': 'application/json'
    }
 
    response = requests.post(url, json=data, headers=headers)
 
    print(f"ステータスコード: {response.status_code}")
    print(f"レスポンス: {response.json()}")
 
 # 認証付きリクエストの例
 def get_protected_resource(token):
    url = f'{API_ENDPOINT}/protected'
 
    headers = {
       'Authorization': f'Bearer {token}'
    }
 
    response = requests.get(url, headers=headers)
 
    print(f"ステータスコード: {response.status_code}")
    print(f"レスポンス: {response.json()}")
 
 if __name__ == '__main__':
    get_users()
    # create_user()
    # get_protected_resource('YOUR_TOKEN_HERE')



セキュリティ

認証と認可

API Gatewayは複数の認証方式をサポートしている。

1. APIキー

最もシンプルな認証方式である。
開発環境やパートナーAPIに適している。

APIキーの作成手順

  1. API Gatewayコンソールで [APIキー] を選択する。
  2. [APIキーの作成] を選択する。
  3. 名前を入力する。
  4. [保存] を選択する。
  5. 作成されたAPIキーの値を控えておく。


使用量プランの作成

  1. [使用量プラン] を選択する。
  2. [作成] を選択する。
  3. プラン名を入力する。
  4. スロットリング設定を行う。
    • レート : 秒あたりのリクエスト数
    • バースト : 一時的な急増を許容する数
  5. クォータ設定を行う。
    • 1日、1週間、または1ヶ月あたりのリクエスト数上限
  6. APIステージを関連付ける。
  7. APIキーを関連付ける。


メソッドでのAPIキー要求の設定

  1. メソッドを選択する。
  2. [メソッドリクエスト] を選択する。
  3. [APIキーの必要性] を true に設定する。
  4. APIを再デプロイする。


クライアントからの使用方法

 curl https://abc123def4.execute-api.ap-northeast-1.amazonaws.com/dev/users \
    -H "x-api-key: YOUR_API_KEY_HERE"


2. IAM認証

AWS IAMを使用した認証である。AWSサービス間の連携に適している。

メソッドでのIAM認証の設定

  1. メソッドを選択する。
  2. [メソッドリクエスト] を選択する。
  3. [承認] で AWS_IAM を選択する。
  4. APIを再デプロイする。


Python (boto3) からの署名付きリクエスト

 import requests
 from requests_aws4auth import AWS4Auth
 import boto3
 
 # AWS認証情報の取得
 session = boto3.Session()
 credentials = session.get_credentials()
 
 # AWS4Auth の作成
 auth = AWS4Auth(
    credentials.access_key,
    credentials.secret_key,
    'ap-northeast-1',
    'execute-api',
    session_token=credentials.token
 )
 
 # リクエストの送信
 url = 'https://abc123def4.execute-api.ap-northeast-1.amazonaws.com/dev/users'
 response = requests.get(url, auth=auth)
 
 print(response.json())


※注意
requests_aws4authのインストールが必要である。

pip3 install requests-aws4auth


3. Cognito認証

ユーザ管理が必要なアプリケーションに適している。

Cognitoユーザープールの作成

  1. Amazon Cognito コンソールで [ユーザープールを作成] を選択する。
  2. 認証フローを設定する。
  3. ユーザー名とパスワードの要件を設定する。
  4. アプリクライアントを作成する。
  5. ユーザープールIDとアプリクライアントIDを控えておく。


API Gatewayでのオーソライザーの設定

  1. API Gatewayコンソールで [オーソライザー] を選択する。
  2. [新しいオーソライザーの作成] を選択する。
  3. タイプで Cognito を選択する。
  4. Cognitoユーザープールを選択する。
  5. トークンソースを入力する。
    例 : Authorization
  6. [作成] を選択する。


メソッドでのオーソライザーの適用

  1. メソッドを選択する。
  2. [メソッドリクエスト] を選択する。
  3. [承認] で作成したオーソライザーを選択する。
  4. APIを再デプロイする。


4. Lambda オーソライザー

カスタム認証ロジックが必要な場合に使用する。

Lambda オーソライザー関数の例

 # lambda_authorizer.py
 
 import json
 
 def lambda_handler(event, context):
    token = event['authorizationToken']
    method_arn = event['methodArn']
 
    # トークンの検証ロジック (例: データベースやキャッシュで確認)
    if token == 'valid-token-12345':
       # 許可ポリシーを返す
       return generate_policy('user', 'Allow', method_arn)
    else:
       # 拒否ポリシーを返す
       return generate_policy('user', 'Deny', method_arn)
 
 def generate_policy(principal_id, effect, resource):
    auth_response = {
       'principalId': principal_id
    }
 
    if effect and resource:
       policy_document = {
          'Version': '2012-10-17',
          'Statement': [
             {
                'Action': 'execute-api:Invoke',
                'Effect': effect,
                'Resource': resource
             }
          ]
       }
       auth_response['policyDocument'] = policy_document
 
    # コンテキスト情報を追加 (オプション)
    auth_response['context'] = {
       'userId': '12345',
       'userName': 'yamada'
    }
 
    return auth_response


API Gatewayでの設定

  1. [オーソライザー] を選択する。
  2. [新しいオーソライザーの作成] を選択する。
  3. タイプで Lambda を選択する。
  4. Lambda関数を選択する。
  5. トークンソースを入力する。
    例 : Authorization
  6. [作成] を選択する。


リソースポリシー

API全体へのアクセスを制御する。特定のIPアドレスやVPCからのアクセスを制限できる。

  • IPアドレス制限のポリシー例
 {
    "Version": "2012-10-17",
    "Statement": [
       {
          "Effect": "Allow",
          "Principal": "*",
          "Action": "execute-api:Invoke",
          "Resource": "arn:aws:execute-api:ap-northeast-1:123456789012:abc123def4/*",
          "Condition": {
             "IpAddress": {
                "aws:SourceIp": [
                   "203.0.113.0/24",
                   "198.51.100.0/24"
                ]
             }
          }
       }
    ]
 }


  • VPC制限のポリシー例
 {
    "Version": "2012-10-17",
    "Statement": [
       {
          "Effect": "Allow",
          "Principal": "*",
          "Action": "execute-api:Invoke",
          "Resource": "arn:aws:execute-api:ap-northeast-1:123456789012:abc123def4/*",
          "Condition": {
             "StringEquals": {
                "aws:SourceVpc": "vpc-12345678"
             }
          }
       }
    ]
 }


スロットリング

レート制限を設定してAPIを保護する。

ステージレベルでのスロットリング設定

  1. ステージを選択する。
  2. [設定] タブを選択する。
  3. デフォルトメソッドスロットリングを設定する。
    • レート : 秒あたりのリクエスト数 (例: 100)
    • バースト : 同時リクエスト数 (例: 200)
  4. [変更の保存] を選択する。


メソッドレベルでのスロットリング設定

  1. ステージを選択する。
  2. [設定] タブを選択する。
  3. メソッドスロットリングを追加する。
  4. メソッドとスロットリング値を設定する。
  5. [変更の保存] を選択する。



トラブルシューティング

エラー : "Missing Authentication Token"

  • 原因
    URLが間違っている、または、リソースが存在しない。
  • 解決方法
    APIのURLを確認する。
    リソースパスが正しいか確認する。
    APIがデプロイされているか確認する。


エラー : "{"message":"Forbidden"}" (403)

  • 原因
    認証に失敗した、または、権限がない。
  • 解決方法
    APIキーが正しいか確認する。(APIキー認証の場合)
    x-api-keyヘッダーが含まれているか確認する。
    IAM権限を確認する。(IAM認証の場合)
    オーソライザーの設定を確認する。
    リソースポリシーを確認する。


エラー : "{"message":"Internal server error"}" (500)

  • 原因
    バックエンド (Lambda等) でエラーが発生した。
  • 解決方法
    Lambda関数のCloudWatch Logsを確認する。
    Lambda関数のエラーハンドリングを確認する。
    統合タイムアウト設定を確認する。
    Lambda関数の実行ロールを確認する。


エラー : "{"message":"Endpoint request timed out"}" (504)

  • 原因
    バックエンドの応答がタイムアウトした。
  • 解決方法
    統合タイムアウトを延長する。(最大29秒)
    Lambda関数のタイムアウトを確認する。
    バックエンド処理を最適化する。
    長時間処理の場合は非同期処理を検討する。


CORSエラー

  • 原因
    CORS設定が不足している、または、間違っている。
  • 解決方法
    CORSを有効化する。
    Access-Control-Allow-Originヘッダを確認する。
    Access-Control-Allow-Methodsヘッダを確認する。
    OPTIONSメソッドが存在するか確認する。(REST APIの場合)
    Lambdaレスポンスにヘッダーが含まれているか確認する。


  • Lambda関数でのCORS対応例
 def lambda_handler(event, context):
    return {
       'statusCode': 200,
       'headers': {
          'Content-Type': 'application/json',
          'Access-Control-Allow-Origin': '*',
          'Access-Control-Allow-Methods': 'GET,POST,PUT,DELETE',
          'Access-Control-Allow-Headers': 'Content-Type,Authorization'
       },
       'body': json.dumps({'message': 'Success'})
    }


スロットリングエラー (429)

  • 原因
    リクエスト数がスロットリング制限を超えた。
  • 解決方法
    スロットリング設定を緩和する。
    クライアント側でリトライロジックを実装する。(Exponential Backoff)
    使用量プランを見直す。
    HTTP APIの使用を検討する。(より高いデフォルト制限)


ログの有効化

トラブルシューティングのため、CloudWatch Logsを有効化することを推奨する。

REST APIのログ有効化

  1. ステージを選択する。
  2. [ログ/トレース] タブを選択する。
  3. CloudWatch設定を有効化する。
    • CloudWatch Logs
      チェックを入れる
    • ログレベル
      INFO または ERROR
    • 完全なリクエスト/レスポンスデータのログ記録
      必要に応じてチェック (注意: 機密情報が含まれる可能性)
  4. IAMロールを設定する。
    API Gatewayがログを書き込むためのロールが必要
  5. [変更の保存] を選択する。


HTTP APIのログ有効化

  1. ステージを選択する。
  2. [ログとトレース] を選択する。
  3. アクセスログを有効化する。
  4. CloudWatch Logsのロググループを指定する。
  5. ログ形式を選択する。
    CLF、JSON、XML、CSV等
  6. [保存] を選択する。


X-Rayトレーシング

リクエストの詳細な追跡とパフォーマンス分析にはX-Rayを使用する。

  1. ステージを選択する。
  2. [ログ/トレース] タブを選択する。
  3. X-Ray トレーシングを有効化する。
  4. [変更の保存] を選択する。


X-Rayコンソールでトレースを確認できる。