AWS CognitoをPythonから扱う

# AWS CognitoをPythonから呼び出そうとしたら盛大にハマった
* と言うことでAWS CognitoをBoto3経由で呼び出す時の備忘録として残しておく

## 事前準備
### Cognitoへのアクセスを許可したIAMを作成しておく
### AWS CognitoでUserPoolを作成する
* とりあえず適当に進めていく
<img width="1273" alt="スクリーンショット.png" src="https://qiita-image-store.s3.amazonaws.com/0/155875/0f146296-cf42-2fe8-6bda-d6af893c5afd.png">
<img width="1260" alt="スクリーンショット 1.png" src="https://qiita-image-store.s3.amazonaws.com/0/155875/63470cf1-fea8-4ff4-c009-e8d17af7c838.png">
<img width="1237" alt="スクリーンショット 3.png" src="https://qiita-image-store.s3.amazonaws.com/0/155875/3ffad727-73c2-7f38-bd06-49da03abcc6e.png">
<img width="1244" alt="スクリーンショット 2.png" src="https://qiita-image-store.s3.amazonaws.com/0/155875/a379fc36-9aa7-2c8e-9651-31dfc0aa7127.png">
<img width="1043" alt="スクリーンショット 4.png" src="https://qiita-image-store.s3.amazonaws.com/0/155875/bbf0a73b-b128-db30-b6e7-40ebf23fbc1c.png">
* このアプリクライアントを作成するときに以下の２点を変更。(ハマりパート1)
    * クライアントシークレットを作成のチェックを外す
        * シークレットがあるとパスワードで承認出来ないらしい…？
    * USER_PASSWORD_AUTHにチェック
<img width="1266" alt="スクリーンショット 5.png" src="https://qiita-image-store.s3.amazonaws.com/0/155875/c2c8b4ca-7ac5-6530-b51a-f0fd1c050282.png">

### Python設定
### バージョン
* Python : 3.6.0
* botocore : 1.12.83

### ユーザ作成
```python

import boto3


def cognito_auth(username, email, gender, birthday, nickname):
    # 認証開始
    try:
        aws_client = boto3.client('cognito-idp',
            region_name = 'ap-northeast-1',
            aws_access_key_id = '***',
            aws_secret_access_key = '***',
        )

        # ユーザー作成
        aws_result = aws_client.admin_create_user(
            # cognito設定時のユーザープールID
            UserPoolId='***',
            Username=username,
            UserAttributes=[
                {
                    'Name': 'email',
                    'Value': email
                },
                {
                    'Name': 'gender',
                    'Value': gender
                },
                {
                    'Name': 'birthdate',
                    'Value': birthdate
                },
                {
                    'Name': 'nickname',
                    'Value': nickname
                },
            ],
            # Mailに初期パスワードを送信する
            DesiredDeliveryMediums=['EMAIL']
        )

        # 認証完了
        print(aws_result)

    except:
        # 認証失敗
        print('Error')


cognito_auth('username', 'email', 'gender', 'birthdate', 'nickname')
```

### 承認要求
```python

response = aws_client.initiate_auth(
    # PASSWORDによる承認
    AuthFlow='USER_PASSWORD_AUTH',
    AuthParameters={
        'USERNAME': '***',
        'PASSWORD': '***'
    },
    ClientId='***'
)


print(response)
```

### 承認要求への返答
* 上のプログラムを実行後に帰ってくるChallengeName, Sessionを利用して以下を実行する
    * 今回はChallengeName='NEW_PASSWORD_REQUIRED'

```python

response = aws_client.respond_to_auth_challenge(
    ClientId='***',
    ChallengeName='ChallengeName',
    Session='***',
    ChallengeResponses={
        'NEW_PASSWORD': 'NEW_PASSWORD',
        'USERNAME': 'USERNAME'
    }
)

print(response)

```

* ここまで実行するとACCESS_TOKENがAWSから吐き出される。
* このACCESS_TOKENを使って色々API叩ける。


## 追記(2019/1/26)
#### Cognitoのupdate_atの型
* Cognitoの型がStringしか使えない？  
update_atに値を入れるときに型変換しないとboto3からエラーが帰ってくる  
最終的な宣言方法は以下  
`str(int(time.time()))`


## 今後
### 新しいAPIを使うときには追加していく。