サインインビューの作成
シリアライザ
src/backend/api/accounts/serializers.py
from rest_framework import serializers
from rest_framework_simplejwt.tokens import RefreshToken
from django.contrib.auth.hashers import make_password, check_password # <- check_passwordを追加
...(略)...
# ↓追加
class SignInSerializer(serializers.Serializer):
email = serializers.EmailField()
password = serializers.CharField(write_only=True)
def validate(self, attrs):
email = attrs["email"]
password = attrs["password"]
hashed = hash(email)
# 1. online.User を email_hash で取得
try:
profile = User.objects.get(email_hash=hashed)
except User.DoesNotExist:
raise serializers.ValidationError("メールアドレスまたはパスワードが正しくありません。")
# 2. CustomUser を profile.user から取得
try:
custom_user = CustomUser.objects.get(user=profile)
except CustomUser.DoesNotExist:
raise serializers.ValidationError("メールアドレスまたはパスワードが正しくありません。")
# 3. パスワードチェック
if not check_password(password, custom_user.password):
raise serializers.ValidationError("メールアドレスまたはパスワードが正しくありません。")
# 認証成功
attrs["user"] = custom_user
attrs["profile"] = profile
return attrs
def create(self, validated_data):
custom_user = validated_data["user"]
profile = validated_data["profile"]
refresh = RefreshToken.for_user(custom_user)
return {
"access": str(refresh.access_token),
"refresh": str(refresh),
"user": {
"user_id": str(profile.user_id),
# "email": profile.get_email(),
},
}
# ↑追加
ビュー
src/backend/api/accounts/views.py
from rest_framework.views import APIView
from rest_framework.permissions import AllowAny
from rest_framework.response import Response
from rest_framework import status
from .serializers import SignUpSerializer, SignInSerializer # <- SignInSerializerを追加
...(略)...
# ↓追加
class SignInView(APIView):
permission_classes = (AllowAny,)
def post(self, request):
serializer = SignInSerializer(data=request.data)
if serializer.is_valid():
data = serializer.save()
return Response(data, status=status.HTTP_200_OK)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
# ↑追加
URL マッピング
src/backend/api/accounts/urls.py
from django.urls import path
from .views import SignUpView, SignInView # <- SignInViewを追加
urlpatterns = [
path("signup/", SignUpView.as_view(), name="accounts-signup"),
path("signin/", SignInView.as_view(), name="accounts-signin"), # <- 追加
]
実行確認
バックエンドサーバが起動している状態で、ブラウザで下記 URL にアクセスしてください。
Contentフォームに、例えば下記のように、登録済みのユーザ情報を入力し、POSTボタンをクリックしてください。
{
"email": "foo@example.com",
"password": "secret123"
}
下記のようにレスポンスが返ってきたら OK。
HTTP 200 OK
Allow: POST, OPTIONS
Content-Type: application/json
Vary: Accept
{
"access": "<ACCESS_TOKEN>",
"refresh": "<REFRESH_TOKEN>",
"user": {
"user_id": "<USER_ID>"
}
}
Contentフォームに、例えば下記のように、未登録のユーザ情報を入力し、POSTボタンをクリックしてください。
{
"email": "bar@example.com",
"password": "password123"
}
下記のようにエラーが表示されたら OK。
HTTP 400 Bad Request
Allow: POST, OPTIONS
Content-Type: application/json
Vary: Accept
{
"non_field_errors": [
"メールアドレスまたはパスワードが正しくありません。"
]
}