[Go] aws-sdk-go-v2 を使って SigV4 署名付きの HTTP リクエストを API Gateway に対して送信する

作成日: 2022年04月05日

IAM 認証を設定している API Gateway に対して SigV4 署名付きの HTTP リクエストを送信しているサンプルコードです。

package main

import (
    "context"
    "fmt"
    "io/ioutil"
    "net/http"
    "time"

    v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4"
    "github.com/aws/aws-sdk-go-v2/config"
)

func main() {
    ctx := context.Background()

    cfg, err := config.LoadDefaultConfig(
        ctx,
        config.WithSharedConfigProfile("default"),
    )
    if err != nil {
        panic(err.Error())
    }

    credentials, err := cfg.Credentials.Retrieve(ctx)
    if err != nil {
        panic(err.Error())
    }

    req, err := http.NewRequest(
        http.MethodGet,
        "https://example.execute-api.ap-northeast-1.amazonaws.com/dummy-stage/dummy-endpoint",
        nil,
    )
    if err != nil {
        panic(err.Error())
    }

    hash := "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
    signer := v4.NewSigner()
    signer.SignHTTP(ctx, credentials, req, hash, "execute-api", "ap-northeast-1", time.Now())

    if err != nil {
        panic(err.Error())
    }

    httpClient := new(http.Client)

    response, err := httpClient.Do(req)
    if err != nil {
        panic(err.Error())
    }

    defer response.Body.Close()

    responseBody, err := ioutil.ReadAll(response.Body)
    if err != nil {
        panic(err.Error())
    }

    fmt.Print(string(responseBody))
}

説明

  • config.LoadDefaultConfigaws.Config を生成しています。プロファイルは default を指定しています。
  • http.NewRequest では、API Gateway の URL に対して、ボディが空の GET リクエストを送信する *http.Request を生成しています。
  • 今回はボディが空なので、SigV4 署名で使用する空文字列の SHA256 ハッシュ値を変数 hash に入れておきます。
  • v4.NewSigner()*v4.Signer を生成します。
  • SignHTTP() でリクエストを SigV4 署名しています。
    • 第1引数はコンテキストを渡します。
    • 第2引数は読み込んだ aws.Config から aws.Credentials を渡します。
    • 第3引数は HTTP リクエストを渡します。
    • 第4引数はボディの SHA256 ハッシュ値を渡します。
    • 第5引数はサービス名の文字列を渡します。ここでは API Gateway を起動する execute-api としています。
    • 第6引数はリージョンを表す文字列を渡します。
    • 第7引数は現在の時刻を渡します。
  • 署名した HTTP リクエストを送信します。
Go AWS