APIゲートウェイのオーソライザーを試した内容を記録

# はじめに
認証後のAPI実行方法を考える上で、API Gatewayのオーソライザーについて調査する機会があったため、現時点で理解している利点、実装方法、検証結果を整理する。

# 概要と利点
## 概要
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560730/440939e1-b532-b099-8f19-97b42ce895d0.png)


API GatewayのオーソライザーとはCognito認証後に返却されるIDトークン(もしくはアクセストークン)をAPI Gatewayで検証しそのIDトークンの有効性によってLambdaを実行を許可するかどうかを判断する仕組みである。

## 利点
+ バックエンドで検証コードを書く必要がなくなり、簡単にサーバーレスアーキテクチャが実現できる
+ サーバーレスアーキテクチャにより、余分なコストが削減できる
+ Claim(ユーザーに関する情報)を使用してユーザー情報に関わるビジネスロジックを実現できる
+ ユーザーの属性や役割によって実行権限を分けることができる

# 実装手順


## Cognitoの設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560730/10170b80-4ee8-2f72-6b90-48a3a7f90ea8.png)

今回、ユーザープールはサインインの識別子のオプションをメールアドレスにして作成。あとはデフォルト。

## Lambdaの設定

実装は以下。※APIゲートウェイの出力(event)の中身はRESTかHTTPで異なる。今回はRESTを使用。
```
import json

def lambda_handler(event, context):
    user_id = ""
    if "requestContext" in event and "authorizer" in event["requestContext"]:
        user_id = event["requestContext"]["authorizer"]["claims"]["sub"]

        return {
        'statusCode': 200,
        'body': json.dumps(f'リクエストに成功しました。あなたのuser_idは{user_id}です。')
        }
        
    else:
        return {
            'statusCode': 400,
            'body': json.dumps('リクエストに失敗しました')
        }
```

## API Gatewayの設定

API Gatewayでは主に以下三つ
+ リソース
+ ステージ
+ オーソライザー
を設定する。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560730/3a31ab46-48aa-da6b-3e24-8beef84f9503.png)


### オーソライザー
まず、オーソライザーの設定
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560730/84c1aa51-2a45-26b4-8d13-842cf95377db.png)
先ほど作成したCognitoユーザープールを選択する。


### リソース
次に、リソースの設定。コンソールに表示ではメソッドリクエスト、統合リクエスト、統合レスポンス、メソッドレスポンスとあるが、主に以下2つを設定する
+ メソッドリクエスト:認可と検証するリクエストヘッダーの設定
+ 統合リクエスト：認可した後に実行するLambda


#### メソッドリクエスト
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560730/e5c7da23-0040-9d0e-ebc6-40314e61ac81.png)
先ほど作成したオーソライザーを認可に設定。ここでは認可スコープ、リクエストバリデーターはなし。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560730/326318f1-e133-6eee-6371-94fbf543c72e.png)
HTTPリクエストヘッダーはAuthorizationを記載。これはPostmanで検証にて後述するリクエストヘッダーに含むキー情報である。

#### 統合リクエスト
先ほど作成したLambda関数をセット
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560730/342b373d-bd00-a4bf-7daf-8bd1e021c2bf.png)

先ほど作成したLambdaを設定。
あとはデフォルトでよしなに

:::note warn
本記事では内容を簡潔にするため、詳細な設定手順を省略しているので悪しからず。
:::

### ステージ

任意の名前を
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560730/5e0987f5-9b2c-fc77-f880-a1c32f12706f.png)

ここでurlが発行される。





# 検証
まず、CLIでCognitoにログイン。

```
aws cognito-idp initiate-auth \
  --client-id your_client_id \
  --auth-flow USER_PASSWORD_AUTH \
  --auth-parameters "USERNAME=your_mailaddress,PASSWORD=your_password, SECRET_HASH=your_secret_hash" \
  --region ap-northeast-1
```

ログイン時に返却されたIDトークンをPostmanのヘッダーのAuthorizationの値に貼り付け、API gatewayで発行されたURLに向けて送信
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560730/2cde1561-504b-7c62-9d70-9be22706d6f8.png)


Lambdaに記載した通り、想定通りの挙動を確認。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/560730/136f56c9-e850-9dde-7f20-c25def267add.png)


# まとめ

今回の検証で、ユーザー認証後に返却されたIDトークンを利用してユーザーに応じたビジネスロジックが可能であることがわかった。
今後はCognitoの理解をさらに深めるため、ユーザーに応じた権限を管理する方法も調査したい。