はじめに
AWSのAPIGatewyの認証としてLambdaAuthorizerは使用したことがありますが、Congnito認証は使用したことが無かったため試してみました。
またクライアントがCognitoにアクセスする際、ググるとほとんどがSDKやAWSCLIを使用していました。AWSのサポートに「curlなどで普通にアクセスできないのか?」と質問をしたところ、以下の情報を教えて貰えました。
Cognito UserPool へのサインイン時には、以下の InitiateAuth API が呼ばれているため、Cognito UserPool のエンドポイントに対して InitiateAuth を curl コマンドで呼び出すことで、実現すること自体は可能です。
これらの情報をもとに、Cognito認証に最低限必要と思われるcurlでも叩けるようなAPIリクエストのサンプルをまとめておきます。
共通で必要な情報
Endpoint(東京リージョンの場合)
https://cognito-idp.ap-northeast-1.amazonaws.com/
Method
POST
Header
Content-Type: application/x-amz-json-1.1
X-Amz-User-Agent: test-requets
※これは無くても大丈夫
サインイン
Request
Header
X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth
Body
{
"AuthFlow": "USER_PASSWORD_AUTH",
"ClientId": "${クライアントID}",
"AuthParameters": {
"USERNAME": "${ユーザ名}",
"PASSWORD": "${パスワード}"
}
}
Response
Body(初回サインイン時)
初回サインイン時は仮パスワード状態であり、まだトークンは貰えません。
そのかわりに、パスワード変更時に必要なセッション情報が渡ってきます。
{
"ChallengeName": "NEW_PASSWORD_REQUIRED",
"ChallengeParameters": {
"USER_ID_FOR_SRP": "${ユーザ名}",
"requiredAttributes": "[]",
"userAttributes": "{\"email_verified\":\"true\",\"email\":\"${メールアドレス}\"}"
},
"Session": "${セッション情報}"
}
Body通常サインイン時
初回パスワード変更
Request
Header
X-Amz-Target: AWSCognitoIdentityProviderService.RespondToAuthChallenge
Body
{
"ClientId": "${クライアントID}",
"ChallengeName": "NEW_PASSWORD_REQUIRED",
"ChallengeResponses": {
"NEW_PASSWORD": "${新しいパスワード}",
"USERNAME": "${ユーザ名}"
},
"Session" : "${初回サインインのレスポンスに詰まっているセッション情報}"}
Response
Body
{
"AuthenticationResult": {
"AccessToken": "${アクセストークン}",
"ExpiresIn": 3600,
"IdToken": "${IDトークン}",
"RefreshToken": "${リフレッシュトークン}",
"TokenType": "Bearer"
},
"ChallengeParameters": {}
}
トークンの更新
Request
Header
X-Amz-Target: AWSCognitoIdentityProviderService.InitiateAuth
Body
{
"AuthFlow": "REFRESH_TOKEN_AUTH",
"ClientId": "${クライアントID}",
"AuthParameters": {
"USERNAME": "${ユーザ名}",
"REFRESH_TOKEN": "${リフレッシュトークン}"
}
}
Response
Body
{
"AuthenticationResult": {
"AccessToken": "${新しいアクセストークン}",
"ExpiresIn": 3600,
"IdToken": "${新しいIDトークン}",
"TokenType": "Bearer"
},
"ChallengeParameters": {}
}
パスワード変更(初回以外)
Request
Header
X-Amz-Target: AWSCognitoIdentityProviderService.ChangePassword
Body
{
"AccessToken": "${アクセストークン}",
"PreviousPassword": "${今までのパスワード}",
"ProposedPassword": "${新しく設定したいパスワード}"
}
Response
Body
HTTPステータスコード: 200
{}
※書き漏れではなく空の{}
が返ってきました。
その他メモ(そのうち別記事にする予定)
トークンの有効期限が切れた際のレスポンス
ステータスコード: 401
特徴的なヘッダ(x-amzn-ErrorType): UnauthorizedException
body:
{
"message": "The incoming token has expired"
}