Help us understand the problem. What is going on with this article?

CognitoにSDKやAWSCLI無しでアクセスする(curlなど)

はじめに

AWSのAPIGatewyの認証としてLambdaAuthorizerは使用したことがありますが、Congnito認証は使用したことが無かったため試してみました。

またクライアントがCognitoにアクセスする際、ググるとほとんどがSDKやAWSCLIを使用していました。AWSのサポートに「curlなどで普通にアクセスできないのか?」と質問をしたところ、以下の情報を教えて貰えました。

Cognito UserPool へのサインイン時には、以下の InitiateAuth API が呼ばれているため、Cognito UserPool のエンドポイントに対して InitiateAuth を curl コマンドで呼び出すことで、実現すること自体は可能です。

InitiateAuth - Amazon Cognito Identity Provider

Amazon Cognito ID エンドポイントとクォータ - AWS 全般のリファレンス

これらの情報をもとに、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"
}
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
Comments
No comments
Sign up for free and join this conversation.
If you already have a Qiita account
Why do not you register as a user and use Qiita more conveniently?
You need to log in to use this function. Qiita can be used more conveniently after logging in.
You seem to be reading articles frequently this month. Qiita can be used more conveniently after logging in.
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away
ユーザーは見つかりませんでした