0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

tavernでCognitoから取得したID Tokenを利用したAPIテスト

Last updated at Posted at 2025-02-26

APIのテストでtavernを使ってCognitoの認証情報使ったテストがしたかったので、調べた内容です。

やりたいこと

  • Cognitoから認証で取得したID Tokenを利用してAPIをテストしたい
  • Cognitoの認証情報はSecretsManagerに保存する
  • 環境毎に変数定義したい

ディレクトリ構成

簡単な構成として以下のようなものを作りました。

$ tree
.
├── config
│   ├── dev.yaml
│   └── prd.yaml
├── helper
│   └── auth.py
├── pyproject.toml
└── tests
    ├── __init__.py
    └── myapi.tavern.yaml

config/ の下は環境毎の設定ファイルを置いています。テスト実行時に引数でファイルを指定します。

config/dev.yaml
variables:
  aws:
    secretName: tavern/test/dev # SecretsManagerのSecret名
    region: ap-northeast-1 # AWS Region
  service:
    baseUrl: https://your.domain.com # APIのBaseUrl

helper/ の下にはヘルパー関数を置いて、SecretsManagerから取得した情報を元にID TokenをCognitoから取得しています。引数なども渡せます。

ちなみにSecretsManagerには以下のように認証情報置いています。
image.png

helper/auth.py
import ast
from dataclasses import dataclass
import boto3
from box import Box

@dataclass(frozen=True)
class CognitoCredentials:
    client_id: str
    username: str
    password: str

def _get_secrets(secret_name:str,aws_region:str) -> CognitoCredentials:
    """
    Get the secret from AWS Secrets Manager
    """
    secretsmanager = boto3.client("secretsmanager", region_name=aws_region)
    response = secretsmanager.get_secret_value(SecretId=secret_name)
    secret = ast.literal_eval(response["SecretString"])
    return CognitoCredentials(
        client_id=secret["clientid"],
        username=secret["username"],
        password=secret["password"],
    )


def get_authorization_header(secret_name:str,aws_region:str) -> Box:
    """
    Get the Cognito ID token
    """
    cred = _get_secrets(secret_name,aws_region)
    cognito_idp_client = boto3.client("cognito-idp", region_name=aws_region)
    res = cognito_idp_client.initiate_auth(
        AuthFlow="USER_PASSWORD_AUTH",
        AuthParameters={
            "USERNAME": cred.username,
            "PASSWORD": cred.password,
        },
        ClientId=cred.client_id,
    )
    id_token = res["AuthenticationResult"]["IdToken"]
    return Box({"Authorization": id_token})

tests/ の下にテストファイルを置きます。

  • {} の記法で config/ の下のyamlファイルの値を変数として埋め込めます
  • function で指定した関数に extra_kwargs で引数を渡しています
test_name: Call API with Cognito ID token

stages:
  - name: Cognitoから取得したIDトークンを使ってAPIを実行
    request:
      url: "{service.baseUrl:s}/some/api"
      method: GET
      headers:
        $ext:
          function: helper.auth:get_authorization_header
          extra_kwargs:
            secret_name: "{aws.secretName:s}"
            aws_region: "{aws.region:s}"
    response:
      status_code: 200

pyproject.tomlではpytestの設定を追加しています。tavernで利用されます。

pyproject.toml
[project]
name = "tavern-cognito-token"
version = "0.1.0"
requires-python = ">=3.12"
dependencies = [
    "boto3>=1.36.21",
    "tavern[pytest]==2.11.0",
]

[tool.pytest.ini_options]
addopts = "-ra -s --log-cli-level=INFO"
testpaths = ["tests"]

実行してみる

以下のように --tavern-global-cfg でconfig配下の設定ファイルを指定して実行することで、環境切り替えつつテストが可能です。

uv run py.test --tavern-global-cfg=./config/dev.yaml 
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?