👶

【Flutter × AWS without Amplify】API Gatewayの利用方法

2022/11/30に公開

AWS の API Gateway を利用するときに調べたことメモ。
普段から AWS 触っている人にとっては認証情報や署名バージョン4の
取扱に慣れていると思われるので、そこまで需要はないかも。

コード内のコメントに解釈を記載していますが、誤りがありましたら
コメントや DM でご連絡いただけると幸いです。

環境

フレームワーク:Flutter(Dart)
パッケージの:amazon_cognito_identity_dart_2 ※非公式
コードの引用元:上記パッケージのサンプルコード

use this package

https://pub.dev/packages/amazon_cognito_identity_dart_2

Get AWS Credentials

import 'package:amazon_cognito_identity_dart_2/cognito.dart';

// CognitoUserPoolオブジェクトにユーザープールの値を設定
final userPool = CognitoUserPool(
  'ap-southeast-1_xxxxxxxxx',
  'xxxxxxxxxxxxxxxxxxxxxxxxxx',
);

// CognitoUserオブジェクトを設定 ※この場合、ユーザー名にメールアドレスを利用している
final cognitoUser = CognitoUser('email@inspire.my', userPool);

// AuthenticationDetailsオブジェクトを設定、ここに認証情報を格納する
final authDetails = AuthenticationDetails(
    username: 'email@inspire.my',
    password: 'Password001',
);

// セッションを開始
final session = await cognitoUser.authenticateUser(authDetails);

// CognitoCredentialsオブジェクトを設定
// 誤:xxx~xxxの箇所にはそのアクセスするユーザーのユーザーIDが入る
//  正:フェデレーティッドアイデンティティプールを作成し、そのIDプールのIDを入れる
final credentials = CognitoCredentials(
    'ap-southeast-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', userPool);

// セッション情報を用いてCredentialsを取得
await credentials.getAwsCredentials(session.getIdToken().getJwtToken());
print(credentials.accessKeyId);
print(credentials.secretAccessKey);
print(credentials.sessionToken);

API   Gateway

import 'package:http/http.dart' as http;
import 'package:amazon_cognito_identity_dart_2/cognito.dart';
import 'package:amazon_cognito_identity_dart_2/sig_v4.dart';

void main() async {
    // ===========認証情報の用意===========

  // CognitoCredentialsオブジェクトを作成
  // 誤:xxx~xxxの箇所にはそのアクセスするユーザーのユーザーIDが入る
  //  正:フェデレーティッドアイデンティティプールを作成し、そのIDプールのIDを入れる
  final credentials = CognitoCredentials(
      'ap-southeast-1:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx', userPool);

  // Credentialsを取得
  await credentials.getAwsCredentials(session.getIdToken().getJwtToken());

  // API Gatewayのエンドポイントを設定
  const endpoint =
      'https://xxxx.execute-api.ap-southeast-1.amazonaws.com/dev';

  // ===========署名の用意===========

  // AwsSigV4ClientオブジェクトにSigV4(AWSのAPIを利用する上での署名情報)の設定
  final awsSigV4Client = AwsSigV4Client(
      credentials.accessKeyId, credentials.secretAccessKey, endpoint,
      sessionToken: credentials.sessionToken,
      region: 'ap-southeast-1');

  // SigV4Requestオブジェクトに署名リクエストに必要な情報を格納
  final signedRequest = SigV4Request(awsSigV4Client,
      method: 'POST',
      path: '/projects',
      headers: Map<String, String>.from(
          {'header-1': 'one', 'header-2': 'two'}),
      queryParams: Map<String, String>.from({'tracking': 'x123'}),
      body: Map<String, dynamic>.from({'color': 'blue'}));


  // ===========API Gatewayにアクセス===========

  // APIから返ってくるHTTPレスポンスを受け取るために変数を定義
  http.Response response;

  try {
      // API GatewayにHTTP POSTでアクセス
    response = await http.post(
      signedRequest.url,
      headers: signedRequest.headers,
      body: signedRequest.body,
    );
  } catch (e) {
    print(e);
  }

  // HTTPレスポンスのbodyを確認
  print(response.body);
}

Credentials の設定

https://zenn.dev/gekitenius/articles/e2cdc16b98e292

補足:署名バージョン 4 の署名プロセス

エンドポイントには通常、サービス名とリージョンが含まれており、どちらも Credential 認証パラメータの一部として使用する必要があります。

https://docs.aws.amazon.com/ja_jp/general/latest/gr/signature-version-4.html

Discussion