Edited at

Python requests で AWS Cognito の認証をする


やりたいこと

Python の Requests (= 外からの HTTPS リクエスト) で、AWS Cognito の認証をしたい。


やりかた


前提


  • AWS Cognito のユーザープール でアプリクライアントを作成している。

  • このとき、USER_PASSWORD_AUTH のみをチェックしている

  • region は ap-northeast-1


経緯

https://github.com/aws-amplify/amplify-js を読んで、ログインに対応する部分を見つけ出す。

以下のあたりが使えそう。


packages/src/CognitoUser.jsより抜粋

  initiateAuth(authDetails, callback) {

const authParameters = authDetails.getAuthParameters();
authParameters.USERNAME = this.username;

const jsonReq = {
AuthFlow: 'CUSTOM_AUTH',
ClientId: this.pool.getClientId(),
AuthParameters: authParameters,
ClientMetadata: authDetails.getValidationData(),
};
if (this.getUserContextData()) {
jsonReq.UserContextData = this.getUserContextData();
}

this.client.request('InitiateAuth', jsonReq, (err, data) => {
if (err) {
return callback.onFailure(err);
}
const challengeName = data.ChallengeName;
const challengeParameters = data.ChallengeParameters;

if (challengeName === 'CUSTOM_CHALLENGE') {
this.Session = data.Session;
return callback.customChallenge(challengeParameters);
}
this.signInUserSession = this.getCognitoUserSession(data.AuthenticationResult);
this.cacheTokens();
return callback.onSuccess(this.signInUserSession);
});
}



packages/src/Client.jsより抜粋

 /**

* Makes an unauthenticated request on AWS Cognito Identity Provider API
* using fetch
* @param {string} operation API operation
* @param {object} params Input parameters
* @param {function} callback Callback called when a response is returned
* @returns {void}
*/

request(operation, params, callback) {
const headers = {
'Content-Type': 'application/x-amz-json-1.1',
'X-Amz-Target': `AWSCognitoIdentityProviderService.${operation}`,
'X-Amz-User-Agent': this.userAgent,
};

const options = {
headers,
method: 'POST',
mode: 'cors',
cache: 'no-cache',
body: JSON.stringify(params),
};

let response;
let responseJsonData;

fetch(this.endpoint, options)



結果

以下のスクリプトで、 JWT Token を get できた。

import requests

# 初期設定
client_id = "クライアントID"
username = "ユーザネーム"
password = "パスワード"
region = "ap-northeast-1"

# リクエスト
endpoint = "https://cognito-idp.%s.amazonaws.com" % region
headers = {
'Content-Type': "application/x-amz-json-1.1",
'X-Amz-Target': "AWSCognitoIdentityProviderService.InitiateAuth",
'X-Amz-User-Agent': "python-requests"
}
res = requests.post(
endpoint,
headers=headers,
data=json.dumps({
"AuthFlow": "USER_PASSWORD_AUTH",
"ClientId": client_id,
"AuthParameters": {
"USERNAME": username,
"PASSWORD": password
},
})
)
print(res.json())


参考文献

https://github.com/aws-amplify/amplify-js