Fix duplicate user registration error

This commit is contained in:
2025-08-31 12:08:36 +09:00
parent 71b073229e
commit e9c6838171
2 changed files with 44 additions and 0 deletions

View File

@ -247,6 +247,7 @@ urlpatterns += [
# App Version Management # App Version Management
path('app/version-check/', app_version_check, name='app_version_check'), path('app/version-check/', app_version_check, name='app_version_check'),
path('api/app/version-check/', app_version_check, name='app_version_check_duplicate'), # クライアントの誤ったURL対応
path('app/version-management/', AppVersionManagementView.as_view(), name='app_version_management'), path('app/version-management/', AppVersionManagementView.as_view(), name='app_version_management'),
# Multi-Image Upload API # Multi-Image Upload API

View File

@ -74,6 +74,8 @@ from django.utils.encoding import force_str
import logging import logging
from datetime import datetime,timedelta from datetime import datetime,timedelta
from django.core.cache import cache
import time
from django.contrib.gis.measure import D from django.contrib.gis.measure import D
from django.contrib.gis.geos import Point from django.contrib.gis.geos import Point
@ -2277,6 +2279,28 @@ class TempUserRegistrationView(APIView):
def post(self, request): def post(self, request):
email = request.data.get('email') email = request.data.get('email')
# レート制限: 同じIPアドレスからの重複リクエストを防ぐ
client_ip = self.get_client_ip(request)
cache_key_ip = f"register_rate_limit:{client_ip}"
cache_key_email = f"register_email_limit:{email}"
# 同じIPからの連続リクエストを制限1分間に最大3回
ip_requests = cache.get(cache_key_ip, 0)
if ip_requests >= 3:
logger.warning(f"レート制限: IP {client_ip} からの過剰なリクエスト")
return Response({
"error": "リクエストが多すぎます。1分後に再試行してください。"
}, status=status.HTTP_429_TOO_MANY_REQUESTS)
# 同じメールアドレスへの連続リクエストを制限30秒間に1回
email_request_time = cache.get(cache_key_email)
current_time = time.time()
if email_request_time and (current_time - email_request_time) < 30:
logger.warning(f"メール送信制限: {email} への重複リクエスト")
return Response({
"error": "同じメールアドレスへの再送信は30秒後に可能です。"
}, status=status.HTTP_429_TOO_MANY_REQUESTS)
# 本登録済みのユーザーチェック # 本登録済みのユーザーチェック
if CustomUser.objects.filter(email=email).exists(): if CustomUser.objects.filter(email=email).exists():
logger.warning(f"既に本登録されているメールアドレスでの仮登録が試みられました。Email: {email}") logger.warning(f"既に本登録されているメールアドレスでの仮登録が試みられました。Email: {email}")
@ -2289,6 +2313,11 @@ class TempUserRegistrationView(APIView):
reverse('rog:verify-email', kwargs={'verification_code': temp_user.verification_code}) reverse('rog:verify-email', kwargs={'verification_code': temp_user.verification_code})
) )
send_verification_email(temp_user, verification_url) send_verification_email(temp_user, verification_url)
# キャッシュを更新
cache.set(cache_key_ip, ip_requests + 1, 60) # 1分間
cache.set(cache_key_email, current_time, 30) # 30秒間
logger.info(f"既に仮登録されているユーザーに招待メールを再送信しました。Email: {email}") logger.info(f"既に仮登録されているユーザーに招待メールを再送信しました。Email: {email}")
return Response({"message": "既に仮登録は行われていますが、招待メールを再送信しました。"}, status=status.HTTP_200_OK) return Response({"message": "既に仮登録は行われていますが、招待メールを再送信しました。"}, status=status.HTTP_200_OK)
except TempUser.DoesNotExist: except TempUser.DoesNotExist:
@ -2310,10 +2339,24 @@ class TempUserRegistrationView(APIView):
reverse('rog:verify-email', kwargs={'verification_code': verification_code}) reverse('rog:verify-email', kwargs={'verification_code': verification_code})
) )
send_verification_email(temp_user, verification_url) send_verification_email(temp_user, verification_url)
# キャッシュを更新
cache.set(cache_key_ip, ip_requests + 1, 60) # 1分間
cache.set(cache_key_email, current_time, 30) # 30秒間
logger.info(f"新規ユーザーを仮登録し、招待メールを送信しました。Email: {email}") logger.info(f"新規ユーザーを仮登録し、招待メールを送信しました。Email: {email}")
return Response({"message": "仮登録が完了しました。招待メールを送信しました。"}, status=status.HTTP_201_CREATED) return Response({"message": "仮登録が完了しました。招待メールを送信しました。"}, status=status.HTTP_201_CREATED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST) return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
def get_client_ip(self, request):
"""クライアントIPアドレスを取得"""
x_forwarded_for = request.META.get('HTTP_X_FORWARDED_FOR')
if x_forwarded_for:
ip = x_forwarded_for.split(',')[0]
else:
ip = request.META.get('REMOTE_ADDR')
return ip
#serializer = TempUserRegistrationSerializer(data=request.data) #serializer = TempUserRegistrationSerializer(data=request.data)