View on GitHub

サインインビューの作成

Home

サインインビューの作成

シリアライザ

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": [
        "メールアドレスまたはパスワードが正しくありません。"
    ]
}