< 一覧に戻る
Django 認証に Cognito を組み込む
Django 認証バックエンドに Cognito を設定し、API から認証を実行可能とするバックエンドの例
AWS
article
Django
Python
Source Code: https://github.com/kemu3007/django-cognito
認証バックエンドを設定することで Django Admin 等のデフォルト機能を利用可能としています。
トークン類はセッションとして DB に保存しバックエンドからのみ参照可能です。
## `urls.py`
```python
from django.contrib import admin
from django.urls import path
from auth.views import auth_api
urlpatterns = [path("admin/", admin.site.urls), path("auth/", auth_api.urls)]
```
## `backend.py`
```python
import requests
from django.conf import settings
from django.contrib.auth.backends import BaseBackend
from django.contrib.auth.models import User
from django.db.models.base import Model
class CognitoBackend(BaseBackend):
def authenticate(self, request, username=None, password=None):
response = requests.post(
settings.COGNITO_EP,
json={
"AuthFlow": "USER_PASSWORD_AUTH",
"ClientId": settings.COGNITO_CLIENT_ID,
"AuthParameters": {"USERNAME": username, "PASSWORD": password},
},
headers={
"Content-Type": "application/x-amz-json-1.1",
"X-Amz-Target": "AWSCognitoIdentityProviderService.InitiateAuth",
},
)
if response.status_code != 200:
return None
request.session["cognito"] = response.json()
user, _ = User.objects.get_or_create(
username=username, is_staff=True, is_superuser=True
)
return user
def get_user(self, user_id: int):
return User.objects.filter(pk=user_id).first()
```
## `views.py`
```python
import jwt
import requests
from django.conf import settings
from django.contrib.auth import authenticate, logout
from ninja import NinjaAPI, Schema
auth_api = NinjaAPI()
class LoginSchema(Schema):
username: str
password: str
class LoginResponseSchema(Schema):
pk: int
username: str
@auth_api.post("/login", response=LoginResponseSchema)
def login(request, input: LoginSchema):
return authenticate(request, username=input.username, password=input.password)
class SignUpSchema(Schema):
username: str
password: str
email: str
@auth_api.post("/signUp")
def signUp(request, input: SignUpSchema):
response = requests.post(
settings.COGNITO_EP,
json={
"ClientId": settings.COGNITO_CLIENT_ID,
"Username": input.username,
"Password": input.password,
"UserAttributes": [{"Name": "email", "Value": input.email}],
},
headers={
"Content-Type": "application/x-amz-json-1.1",
"X-Amz-Target": "AWSCognitoIdentityProviderService.SignUp",
},
)
return response.json()
class ConfirmSignUpSchema(Schema):
username: str
code: str
@auth_api.post("/confirmSignUp")
def confirmSignUp(request, input: ConfirmSignUpSchema):
response = requests.post(
settings.COGNITO_EP,
json={
"ClientId": settings.COGNITO_CLIENT_ID,
"Username": input.username,
"ConfirmationCode": input.code,
},
headers={
"Content-Type": "application/x-amz-json-1.1",
"X-Amz-Target": "AWSCognitoIdentityProviderService.ConfirmSignUp",
},
)
return response.json()
@auth_api.get("/getUser")
def getUser(request):
try:
jwks_client = jwt.PyJWKClient(settings.COGNITO_JWK_EP)
token = request.session["cognito"]["AuthenticationResult"]["IdToken"]
payload = jwt.decode(
token,
jwks_client.get_signing_key_from_jwt(token),
audience=settings.COGNITO_CLIENT_ID,
algorithms=["RS256"],
)
return payload
except (jwt.exceptions.PyJWTError, KeyError) as e:
return None
```