Files
chunyu_project/user/views/slider_captcha.py
T

107 lines
3.9 KiB
Python

from rest_framework.permissions import AllowAny
from adrf.views import APIView
from rest_framework import status
from drf_yasg.utils import swagger_auto_schema
from drf_yasg import openapi
from chunyu_project.common_schemas import success_response, error_response, unauthorized_response, not_found_response
from utils.slider_captcha import (
generate_slider_captcha,
verify_slider_captcha,
verify_slider_trajectory,
SliderCaptchaError
)
from utils.response_codes import (
ResponseCode,
create_standardized_response,
create_standardized_error_response,
)
class SliderCaptchaGenerateView(APIView):
permission_classes = [AllowAny]
@swagger_auto_schema(
tags=['验证码'],
operation_summary='生成滑块验证码',
operation_description='生成新的滑块验证码,返回背景图、滑块图和验证 key',
responses={200: success_response, 500: error_response},
)
def get(self, request):
try:
captcha_data = generate_slider_captcha()
return create_standardized_response(
data=captcha_data,
code=ResponseCode.SUCCESS,
status_code=status.HTTP_200_OK
)
except Exception as e:
return create_standardized_error_response(
message=str(e),
code=ResponseCode.SERVER_INTERNAL_ERROR,
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR
)
class SliderCaptchaVerifyView(APIView):
permission_classes = [AllowAny]
@swagger_auto_schema(
tags=['验证码'],
operation_summary='验证滑块验证码',
operation_description='验证滑块验证码结果,支持滑动轨迹可选',
request_body=openapi.Schema(
type=openapi.TYPE_OBJECT,
properties={
'captcha_key': openapi.Schema(type=openapi.TYPE_STRING, description='验证码 key'),
'x_position': openapi.Schema(type=openapi.TYPE_INTEGER, description='滑块 X 坐标'),
'trajectory': openapi.Schema(type=openapi.TYPE_ARRAY, items=openapi.Items(type=openapi.TYPE_NUMBER), description='滑动轨迹数组'),
},
),
responses={200: success_response, 400: error_response, 500: error_response},
)
def post(self, request):
captcha_key = request.data.get('captcha_key')
x_position = request.data.get('x_position')
trajectory = request.data.get('trajectory')
if not captcha_key or x_position is None:
return create_standardized_error_response(
message='缺少必要参数',
code=ResponseCode.PARAMETER_ERROR,
status_code=status.HTTP_400_BAD_REQUEST
)
try:
x_position = int(x_position)
except (ValueError, TypeError):
return create_standardized_error_response(
message='位置参数无效',
code=ResponseCode.PARAMETER_ERROR,
status_code=status.HTTP_400_BAD_REQUEST
)
try:
if trajectory:
verified = verify_slider_trajectory(captcha_key, x_position, trajectory)
else:
verified = verify_slider_captcha(captcha_key, x_position)
return create_standardized_response(
data={'verified': verified},
code=ResponseCode.SUCCESS,
status_code=status.HTTP_200_OK
)
except SliderCaptchaError as e:
return create_standardized_error_response(
message=str(e),
code=ResponseCode.CAPTCHA_EXPIRED,
status_code=status.HTTP_400_BAD_REQUEST
)
except Exception as e:
return create_standardized_error_response(
message=str(e),
code=ResponseCode.SERVER_INTERNAL_ERROR,
status_code=status.HTTP_500_INTERNAL_SERVER_ERROR
)