やること
python-joseではjwtを扱うことができます。
これを利用してcognitoのアクセストークンが正しいものかを検証します。
これでユーザーがログインしているかをAPI側で判別することができます。
流れのイメージ
- 指定したcognitoのユーザープールの鍵をもらう。
- 検証したいアクセストークンのヘッダーを見て使用する鍵を選ぶ(一致するかを確認する)。
- 鍵を使ってアクセストークンをデコードする。
3.でエラーが起きなければ成功
コード
前提
アクセストークンの発行(ログイン処理)と、アクセストークン(リクエスト)の受け取りは実装されている
検証部分
# cognitoからJWKsを取得
jwks_url = f"https://cognito-idp.ap-northeast-1.amazonaws.com/{RESIDENT_POOL_ID}/.well-known/jwks.json"
jwks = requests.get(jwks_url).json()
# アクセストークンのヘッダーからキーID (kid) を取得
headers = jwt.get_unverified_headers(access_token)
kid = headers["kid"]
# JWKsから対応するキーを見つける
key = {}
for jwk_data in jwks["keys"]:
if jwk_data["kid"] == kid:
key = jwk_data
break
# アクセストークンの署名を検証
rsa_key = jwk.construct(key)
decoded_access_token = jwt.decode(
access_token,
rsa_key,
algorithms=["RS256"],
audience=RESIDENT_POOL_CLIENT_ID,
)
例外処理とか入れたらいい感じ。
# (…省略)
try:
decoded_access_token = jwt.decode(
access_token,
rsa_key,
algorithms=["RS256"],
audience=RESIDENT_POOL_CLIENT_ID,
)
except Exception as e: # 適切なエラーを指定した方がいいかも
# fastapiを使っている場合
raise HTTPException(
status_code=401,
detail=f"The token is invalid.({e})",
)