API Gateway WebSocket + Lambdaオーソライザー構成

CloudFormationを使った実装ガイド

2025年3月26日

📌 はじめに

AWSのAPI Gateway (v2)Lambdaオーソライザーを組み合わせることで、WebSocketの接続時に認証を実装できます。

API Gateway v2: WebSocket APIを提供

Lambdaオーソライザー: リクエストを処理前に認証判断

CloudFormation: AWSリソースを宣言的に定義

✏️ 今回はクエリパラメータでトークンを渡し、$connect時に認証を行う方法を紹介します!

🔄 認証フロー

1

クライアントからの接続要求

wss://{api-url}?token=XYZ

2

API Gatewayがオーソライザーを呼び出し

$connectルートに対するリクエストを検証

3

Lambdaオーソライザーでトークン検証

IAMポリシーを返却(許可/拒否)

4

API Gatewayがポリシーを評価

許可なら接続続行、拒否ならエラー応答

5

$connectルートのLambda処理

接続確立後の初期処理を実行

🔑 Lambdaオーソライザー関数

Node.jsで実装したシンプルなオーソライザー例:

exports.handler = async (event) => { // クエリパラメータからトークンを取得 const token = event.queryStringParameters?.token; // トークン検証(例:固定値と比較) const validToken = "my-secret-token"; const effect = token === validToken ? "Allow" : "Deny"; // IAMポリシーを生成して返却 return { principalId: effect === "Allow" ? "user123" : "unauthorized", policyDocument: { Version: "2012-10-17", Statement: [{ Action: "execute-api:Invoke", Effect: effect, Resource: event.methodArn }] } }; };

💡 実際の運用では、JWT検証データベース参照などでより厳密に検証します

🏗️ CloudFormationリソース構成

🌐 AWS::ApiGatewayV2::Api

WebSocket API本体を定義

・ProtocolType: WEBSOCKET

・RouteSelectionExpression: $request.body.action

🔐 AWS::ApiGatewayV2::Authorizer

Lambdaオーソライザー設定

・AuthorizerType: REQUEST

・IdentitySource: querystring.token

🛣️ AWS::ApiGatewayV2::Route

$connectルートの定義

・RouteKey: $connect

・AuthorizationType: CUSTOM

🔌 AWS::ApiGatewayV2::Integration

Lambdaとの統合設定

・IntegrationType: AWS_PROXY

🚀 AWS::ApiGatewayV2::Stage

デプロイ用ステージ設定

・例: Prodステージ

⚡ AWS::Lambda::Function

2つのLambda関数を定義

・オーソライザー用: トークン検証

・接続ハンドラ用: $connect処理

🔒 AWS::Lambda::Permission

Lambda呼び出し権限設定

・Principal: apigateway.amazonaws.com

📝 実装のポイント

AuthorizerTypeには"REQUEST"を指定

IdentitySourceにクエリパラメータを指定

$connectルートにのみオーソライザーを設定可能

✅ Lambda関数はIAMポリシーを返却すること

Lambda::PermissionでAPI Gatewayからの呼び出し権限を付与

📌 WebSocket APIでオーソライザーを使えるのは
$connectルートのみ

📋 CloudFormationテンプレート例

全体を構成するYAMLテンプレートの一部:

AWSTemplateFormatVersion: "2010-09-09" Description: "WebSocket API with Lambda Authorizer" Resources: # WebSocket API定義 WebSocketApi: Type: AWS::ApiGatewayV2::Api Properties: Name: MyWebSocketApi ProtocolType: WEBSOCKET RouteSelectionExpression: $request.body.action # Lambdaオーソライザー設定 MyWebSocketAuthorizer: Type: AWS::ApiGatewayV2::Authorizer Properties: Name: MyWebSocketAuthorizer ApiId: !Ref WebSocketApi AuthorizerType: REQUEST IdentitySource: - route.request.querystring.token AuthorizerUri: !Sub > arn:${AWS::Partition}:apigateway: ${AWS::Region}:lambda:path/2015-03-31/ functions/${MyAuthorizerFunction.Arn}/ invocations # $connectルート用のLambda統合 ConnectIntegration: Type: AWS::ApiGatewayV2::Integration Properties: ApiId: !Ref WebSocketApi IntegrationType: AWS_PROXY IntegrationUri: !GetAtt ConnectHandlerFunction.Arn # $connectルート定義 ConnectRoute: Type: AWS::ApiGatewayV2::Route Properties: ApiId: !Ref WebSocketApi RouteKey: $connect AuthorizationType: CUSTOM AuthorizerId: !Ref MyWebSocketAuthorizer Target: !Join - "/" - ["integrations", !Ref ConnectIntegration]

💡 CloudFormationテンプレート全体はもっと長いですが、ここでは主要な部分のみ抜粋しています。

📚 用語解説

WebSocket API (API Gateway v2)

双方向通信を可能にするAPI

特殊ルート:$connect $disconnect

Lambdaオーソライザー

リクエストを検証するカスタムLambda関数

種類:REQUEST TOKEN

IAMポリシー

AWSリソースへのアクセス権限を定義

効果:Allow Deny

IdentitySource

認証情報の取得元を指定

例:querystring header

🎯 実装のメリット

接続時点で認証が行える

カスタムロジックで柔軟な認証が可能

不正アクセスによるリソース消費を防止

CloudFormationでインフラをコード化

統一的な権限管理が実現可能

🔐 安全なWebSocketアプリケーションの
基盤として活用しましょう!