NOTE: English version is here.
Amazon API Gateway WebSocket APIにCognito認証を組み込むサンプルです。
Lambda AuthorizerとAPI GatewayのためのLambda関数と、バックエンドデプロイのためのCDKコード、動作確認のためのフロントエンドの実装が含まれます。
Note
AppSync Eventsでの実装例も追加しました。こちらはCognito UserPoolを利用した認証の仕組みが隠蔽されるため、ユーザー側の実装はよりシンプルになります。詳細はecho-events.tsx
(React)と events.ts
(CDK)もご覧ください。
本サンプルは、WebSocket APIでのCognito JWT認証を実現するための最小限のアーキテクチャを実装しています。
実装の詳細は、実装の説明の節を参照してください。
本アーキテクチャを他のシステムと連携する際は、DynamoDBのテーブルに保存されたCognitoユーザーIDとWebSocket Connection IDのペアを利用することも可能です。
前提条件: 下記が準備・インストールされていることを前提とします:
- IAM権限の設定
npm
のインストール
バックエンドは下記のコマンドによりデプロイしてください。
CDKについての詳細は、Getting started with the AWS CDKをご覧ください。
cd cdk
npm ci
npx cdk deploy --require-approval never
デプロイが完了すると、CLIに下記のメッセージが表示されます。
Outputs:
BackendWebSocketStack.AppSyncEventsEndpoint = https://xxxxx.appsync-api.ap-northeast-1.amazonaws.com/event
BackendWebSocketStack.Region = ap-northeast-1
BackendWebSocketStack.UserPoolId = ap-northeast-1_xxxxxxx
BackendWebSocketStack.UserPoolWebClientId = xxxxxxxxxxxxxxxxxxxxxxxxxx
BackendWebSocketStack.WebSocketEndpoint = wss://xxxxxxxxx.execute-api.ap-northeast-1.amazonaws.com/prod
この情報は次のフロントエンドのセットアップに利用することができます。
フロントエンドはlocalhost:3000
で動作確認します。
下記のように .env.sample
をリネームして必要な項目を埋めてください。
cd frontend
cp .env.sample .env.local
あとは必要なパッケージをインストールして、localhostでlistenさせます。
# frontend ディレクトリ内で実行
npm ci
npm run dev
ブラウザを開き、http://localhost:3000 にアクセスしてください。
下記のAWSリソースを作成するCDKプロジェクトです:
- API Gateway WebSocket API
- Lambda関数 2つ
- WebSocket APIのインテグレーション
- Lambda Authorizer
- Cognito ユーザープール・クライアント
- DynamoDB テーブル
- Cognito userIdとWebSocket接続IDの対応を保存するテーブル
コードは cdk
ディレクトリ以下に存在します。
バックエンドは2つのLambda関数で構成されます。
authorizer
websocket
authorizer
はTypeScriptで実装された、WebSocket API用のLambda authorizerです。
この関数は次の処理を実行します:
idToken
クエリストリングからJWTを取得し、デコード- Cognitoサーバーから、JWT署名の公開鍵を取得
- JWTの
kid
からJWT署名を検証 - その他のClaimを、Lambdaの環境変数で注入された値と比較して検証
実装の詳細は、Verifying a JSON Web Token も参照してください。
websocket
はTypeScriptで実装された、WebSocket APIのインテグレーションです。
この関数はWebSocketのルートに応じて、次の処理を実行します:
$connect
ルート- CognitoのUserIdとWebSocketの接続IDのペアをDynamoDBに保存します
$disconnect
ルート- 接続IDをDynamoDBから削除します
$default
ルート- 送られた内容をそのままエコーバックします
DynamoDBに保存された情報を利用して、他のサーバーから特定のCognitoユーザーにWebSocketメッセージを送信する、といった用途に応用可能です。
Use @connections commands in your backend service
もご参照ください。
フロントエンドは、ReactのSPAで構成されています。
主要なコンポーネントは src/components/echo.tsx
に実装されています。
認証のために、Cognito UserPoolのIDトークンをクエリストリングに付与しています。WebSocket APIの認証方法にはいくつか考えられますが、それぞれトレードオフがあります。詳細はこちらのIssueもご覧ください。
検証が完了した後は、下記のコマンドで作成されたAWSリソースを削除することができます。
cd cdk
npx cdk destroy --force
See CONTRIBUTING for more information.
This library is licensed under the MIT-0 License. See the LICENSE file.