LoginSignup
2
4

More than 1 year has passed since last update.

FastAPI+Serverless FrameworkでCognito認証情報を処理内で取得

Last updated at Posted at 2022-11-21

タイトルの通り、FastAPIで開発したAPIにServerless Frameworkの authorizer で設定したCognito認証の情報をPython内で使う方法です。

ほぼ最小構成で書いてます。

FastAPI+Mangum(Python)

利用しているパッケージです。

pyproject.toml
#省略
[tool.poetry.dependencies]
python = "^3.8"
fastapi = "^0.87.0"
mangum = "^0.16.0"
#省略

/auth というCognito認証情報だけ返すAPIです。

http.py
from fastapi import FastAPI
from mangum import Mangum
from starlette.requests import Request


app = FastAPI()


@app.get("/auth")
def get_auth(request: Request):
    # Cognitoの認証情報がrequest変数の中に入っています
    auth_info = request.scope["aws.event"]["requestContext"]["authorizer"]
    return {"auth": auth_info}


handler = Mangum(app, lifespan="off")

Serverless Framework

以下の通りデプロイします。※ CognitoのUserPoolのARNだけダミーです。

serverless.yml
service: echo-auth

frameworkVersion: "3"

plugins:
  - serverless-python-requirements

custom:
  pythonRequirements:
    usePoetry: true

provider:
  name: aws
  runtime: python3.8
  stage: dev
  region: ap-northeast-1

package:
  patterns:
    - "./**"
    - "./http.py"

functions:
  api:
    handler: http.handler
    memorySize: 128
    events:
      - http:
          path: /auth
          method: GET
          authorizer:
            name: cognito
            arn: arn:aws:cognito-idp:ap-northeast-1:123456789012:userpool/ap-northeast-1_Txxxxxxx

試してみる

CognitoからID Tokenを取得してAPIを実行してみます。

ID_TOKEN=eyJ....
curl -s https://xxxxxxx.execute-api.ap-northeast-1.amazonaws.com/dev/auth -H "Authorization: ${ID_TOKEN}" | jq

以下のような情報が取得可能です。

{
  "auth": {
    "claims": {
      "at_hash": "xxxxxxxxxxxxxxxxxxxx",
      "sub": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "email_verified": "true",
      "iss": "https://cognito-idp.ap-northeast-1.amazonaws.com/ap-northeast-1_Txxxxxx",
      "cognito:username": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "origin_jti": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
      "aud": "xxxxxxxxxxxxxxxxxxxx",
      "token_use": "id",
      "auth_time": "1669009768",
      "exp": "Tue Nov 22 05:49:28 UTC 2022",
      "iat": "Mon Nov 21 05:49:28 UTC 2022",
      "jti": "56a45e94-cd73-4675-93fc-d396260c3880",
      "email": "yusuke.otomo@mail.com"
    }
  }
}

Dependsを使った方法

Dependsを使った方法もあります。こっちの方がスッキリ処理できる要件もあります。

http.py
from fastapi import FastAPI, Depends, Request
from fastapi.exceptions import HTTPException
from mangum import Mangum


def auth_verify(request: Request):
    try:
        auth_info = request.scope["aws.event"]["requestContext"]["authorizer"]
        print(f"auth_verify -> {auth_info}")
    except:
        raise HTTPException(status_code=403)

app = FastAPI()

@app.get("/auth",dependencies=[Depends(auth_verify)])
def get_auth():
    return {"auth": "ok"}


handler = Mangum(app, lifespan="off")

参考

2
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
4