一番簡単なCognitoの例を試す
Posted On 2024-12-10
初めてAWS Cognitoを利用し、TerraformとPythonで認証の基本的な流れを試してみました。ユーザープールの作成から、ユーザー登録、確認、サインインまでの手順を解説します。
目次
はじめに
Cognitoをちゃんと使ったことがなかったので使ってみた。やったことはGPTに「Cognitoの一番簡単な例を出してください」と言って出したもの。以下の通り
- Cognitoのユーザープールとユーザープールクライアントを定義(Terraform)
- Pythonコードからユーザー名、メールアドレスとパスワードを入力し、ユーザープールに登録(signup.py)
- Pythonコードからメールアドレスに送られてくる認証コードを入力しユーザー確認(confirm_user.py)
- Pythonコードからユーザー名とパスワードを入力し、サインインを行い、認証情報を得る
フロントエンドとのつなぎ込みは一切行っておらず、ただのPythonコードで行うのが最初のステップ。
Cognitoのユーザープールとユーザープールクライアントの作成
- ユーザープールはユーザー情報と認証を管理する「場所」
- ユーザープールクライアントはそのユーザープールにアクセスする「アプリケーション」の設定を定義
Terraformで行う。
# Cognitoユーザープールの作成
resource "aws_cognito_user_pool" "example" {
name = "my-first-user-pool"
# パスワードポリシーの設定(必要に応じて調整)
password_policy {
minimum_length = 8
require_uppercase = true
require_lowercase = true
require_numbers = true
require_symbols = true
}
# ユーザー属性の設定
auto_verified_attributes = ["email"]
# その他の設定はデフォルトを使用
}
# ユーザープールクライアントの作成
resource "aws_cognito_user_pool_client" "example" {
name = "my-first-user-pool-client"
user_pool_id = aws_cognito_user_pool.example.id
# フロー設定(必要に応じて調整)
explicit_auth_flows = [
"ALLOW_USER_PASSWORD_AUTH",
"ALLOW_REFRESH_TOKEN_AUTH",
]
# リフレッシュトークンの有効期間(秒)
refresh_token_validity = 30
# クライアントシークレットの無効化(シンプルな例のため)
generate_secret = false
}
# 出力変数の定義
output "user_pool_id" {
description = "Cognito User Pool ID"
value = aws_cognito_user_pool.example.id
}
output "user_pool_client_id" {
description = "Cognito User Pool Client ID"
value = aws_cognito_user_pool_client.example.id
}
terraform apply
するとユーザープールIDと、ユーザープールクライアントのIDが出力する。これを後ほど使う。
user_pool_client_id = "1example23456789"
user_pool_id = "ap-northeast-1_ExaMPle"
ユーザー登録(signup.py)
# signup.py
import boto3
from botocore.exceptions import ClientError
# ユーザープールのIDとクライアントIDを設定
USER_POOL_ID = 'YOUR_USER_POOL_ID' # 例: 'ap-northeast-1_ExaMPle'
CLIENT_ID = 'YOUR_APP_CLIENT_ID' # 例: '1example23456789'
PROFILE_NAME = 'hogehoge'
# Cognito IDPクライアントを初期化
session = boto3.Session(profile_name=PROFILE_NAME)
client = session.client('cognito-idp')
def sign_up(username, password, email):
try:
response = client.sign_up(
ClientId=CLIENT_ID,
Username=username,
Password=password,
UserAttributes=[
{
'Name': 'email',
'Value': email
},
],
)
print(f"サインアップ成功。ユーザー名: {response['UserSub']}")
except ClientError as e:
print(f"サインアップエラー: {e.response['Error']['Message']}")
if __name__ == "__main__":
username = 'testuser1'
password = 'Password123!' # パスワードポリシーに準拠していることを確認
email = 'user@example.com' # メールを受信できるメールアドレスを入力
sign_up(username, password, email)
成功すると以下のようなメッセージが出てくる。
サインアップ成功。ユーザー名: a1b2c3d4-e5f6-7890-ab12-c3d4e5f67890
ユーザー確認(confirm_user.py)
サインアップに成功すると、メールアドレスに確認コードが送られてくる。
次に以下のコードを実行し、ユーザーを認証させる。
# confirm_user.py
import boto3
from botocore.exceptions import ClientError
# ユーザープールのIDとクライアントIDを設定
USER_POOL_ID = 'YOUR_USER_POOL_ID' # 例: 'ap-northeast-1_ExaMPle'
CLIENT_ID = 'YOUR_APP_CLIENT_ID' # 例: '1example23456789'
PROFILE_NAME = 'hogehoge'
# Cognito IDPクライアントを初期化
session = boto3.Session(profile_name=PROFILE_NAME)
client = session.client('cognito-idp')
def confirm_user(username, confirmation_code):
try:
response = client.confirm_sign_up(
ClientId=CLIENT_ID,
Username=username,
ConfirmationCode=confirmation_code,
)
print("ユーザー確認が成功しました。")
except ClientError as e:
print(f"ユーザー確認エラー: {e.response['Error']['Message']}")
if __name__ == "__main__":
username = 'testuser1'
confirmation_code = input("確認コードを入力してください: ")
confirm_user(username, confirmation_code)
メールに送られたコードを入力すると確認に成功するはずである。
確認コードを入力してください: 123456
ユーザー確認が成功しました。
ユーザー確認が成功すると、マネジメントコンソールのCognitoユーザープールに「確認済み」と表示されるはずだ。
サインイン(signin.py)
このようにサインインをすると、
# signin.py
import boto3
from botocore.exceptions import ClientError
USER_POOL_ID = 'YOUR_USER_POOL_ID' # 例: 'ap-northeast-1_ExaMPle'
CLIENT_ID = 'YOUR_APP_CLIENT_ID' # 例: '1example23456789'
PROFILE_NAME = 'hogehoge'
session = boto3.Session(profile_name=PROFILE_NAME)
client = session.client('cognito-idp')
def sign_in(username, password):
try:
response = client.initiate_auth(
ClientId=CLIENT_ID,
AuthFlow='USER_PASSWORD_AUTH',
AuthParameters={
'USERNAME': username,
'PASSWORD': password
},
)
id_token = response['AuthenticationResult']['IdToken']
access_token = response['AuthenticationResult']['AccessToken']
refresh_token = response['AuthenticationResult']['RefreshToken']
print("サインイン成功。")
print(f"IDトークン: {id_token}")
print(f"アクセストークン: {access_token}")
print(f"リフレッシュトークン: {refresh_token}")
except ClientError as e:
print(f"サインインエラー: {e.response['Error']['Message']}")
if __name__ == "__main__":
username = 'testuser1'
password = 'Password123!'
sign_in(username, password)
様々なトークンが出てくる。
IDトークン: eyJraWQiOiJ6MU......
アクセストークン: eyJraWQiOiJ4......
リフレッシュトークン: eyJjdHkiOiJK......
これで簡単なCognitoによる簡単な例を確認できた。
Shikoan's ML Blogの中の人が運営しているサークル「じゅ~しぃ~すくりぷと」の本のご案内
技術書コーナー
北海道の駅巡りコーナー