ruby使ってAWSのcognito認証をやる

##環境
docker
Ruby on Rails

**Gem**
aws-sdk-cognitoidentityprovider

ドキュメント
https://docs.aws.amazon.com/sdk-for-ruby/v3/api/Aws/CognitoIdentityProvider.html

settingとenvで環境変数化しております
サーバー側で管理
service層にまとめています
各メソッドはコントローラー側で
**HogeService.メソッド** で呼び出し

###クライアントのインスタンスを生成

```
def generating_instance
 client = Aws::CognitoIdentityProvider::Client.new(
   :region => ENV.fetch(Settings.AWS[:REGION]),
   :access_key_id => ENV.fetch(Settings.AWS[:ACCESS_KEY_ID]),
   :secret_access_key => ENV.fetch(Settings.AWS[:SECRET_ACCESS_KEY]),
  )
end
```

###ユーザープール作成

```
resp = client.create_user_pool({
  pool_name: "UserPoolNameType", # required
  policies: {
    password_policy: {
      minimum_length: 1,
      require_uppercase: false,
      require_lowercase: false,
      require_numbers: false,
      require_symbols: false,
      temporary_password_validity_days: 1,
    },
  }
})
```

###アプリクライアントを作成

```
resp = client.create_user_pool_client({
  user_pool_id: 'ap-northeast-1_XXXXXXXXX',
  client_name: 'sample-client',
  explicit_auth_flows: ["ADMIN_NO_SRP_AUTH"]
})
```
サーバーベースの認証でサインインAPIを有効にするためにADMIN_NO_SRP_AUTHを追加


###ユーザー登録（作成）

```ruby:
def sign_up
 begin
   resp = generating_instance.sign_up(
    client_id: ENV.fetch(Settings.AWS[:CLIENT_ID]),
    username: username,
    password: password,
    user_attributes: [
     {
      name: "email",
      value: mail_address,
     }
    ],
    validation_data: [
      {
       name: "email",
       value: mail_address,
      }
    ]
   )
  rescue => e
   raise e
  end
 resp
end
```

###確認コードのチェックとメール送信を行う

```
    # 確認コードのチェックとメール送信を行う
    # ==== args
    # params :: 確認コード用認証パラメーター
    def user_confirm_code(params)
      begin
        # 確認コードをチェックする
        generating_instance.confirm_sign_up({
          client_id: ENV.fetch(Settings.AWS[:CLIENT_ID]),
          username: params['username'],
          confirmation_code: code
        })

        # チェックし終わったユーザーの情報を取得する
        resp = generating_instance.admin_get_user({
          user_pool_id: ENV.fetch(Settings.AWS[:USER_POOL_ID]),
          username: params['username']
        })

        #メール送信
        invite_mail(['email'])
      rescue => e
        raise e
      end
      return
    end

    # ユーザーへメール送信
    # ==== args
    # mail_address :: mail_address
    def invite_mail(mail_address)
      res = {}
      res['email'] = mail_address
      InviteMailer.invite(res).deliver
    end

```
InviteMailer内でメールを整形してそのメールアドレスに認証できたかどうか送信


###パスワード変更

```
    def reset
      begin
        resp = generating_instance.admin_set_user_password({
          user_pool_id: ENV.fetch(Settings.AWS[:USER_POOL_ID]),
          username: username,
          password: password,
          permanent: true,
        })
      rescue => e
        raise e
      end
      return
    end
```

### ユーザー削除

```
    # ユーザー削除
    def delete
      begin
        # ユーザーを管理者として削除
        resp = generating_instance.admin_delete_user({
          user_pool_id: ENV.fetch(Settings.AWS[:USER_POOL_ID]),
          username: username,
        })
      rescue => e
        raise e
      end
      return
    end
```

###アクセストークン取得

```
    # ユーザーのトークン作成
    def create_user_token
      begin

      # トークン取得
      resp = generating_instance.admin_initiate_auth(
        user_pool_id: ENV.fetch(Settings.AWS[:USER_POOL_ID]),
        client_id: ENV.fetch(Settings.AWS[:CLIENT_ID]),
        auth_flow: 'ADMIN_NO_SRP_AUTH',
        auth_parameters: {
          USERNAME: username,
          PASSWORD: password,
        }
      )
      rescue => e
        raise e
      end
       #　アクセストークンだけ返す
      resp.authentication_result.access_token
    end
```

**まとめ**
わりと使うはここらへんだと思われます
間違ってたらオシエテクダサイ