from rest_framework.views import APIView from rest_framework.response import Response from rest_framework import status from rest_framework.permissions import AllowAny from django.views.decorators.csrf import csrf_exempt from django.utils.decorators import method_decorator from api.utils.auth import ThirdPartyAuth, ThirdPartyUserManager from django.contrib.auth.models import User import logging logger = logging.getLogger(__name__) @method_decorator(csrf_exempt, name='dispatch') class TokenValidateView(APIView): """ Token验证接口 用户可以通过此接口验证Token是否有效,并获取用户信息 """ permission_classes = [AllowAny] # 允许任何人访问此接口 def post(self, request): """ 验证Token 支持的参数传递方式: 1. JSON: {"token": "your_token"} 2. Form data: token=your_token 3. URL参数: ?token=your_token 4. Header: Authorization: Token your_token """ # 获取Token token = self.get_token_from_request(request) if not token: return Response({ 'valid': False, 'error': 'Token参数缺失', 'message': '请提供Token参数。支持的方式:1) JSON: {"token": "your_token"} 2) Form data: token=your_token 3) URL参数: ?token=your_token 4) Header: Authorization: Token your_token', 'example': { 'curl_header': 'curl -H "Authorization: Token 0c47b3d5b1aa561a5032f50e95bf069afa9a9e55" http://your-domain/api/token/validate/', 'curl_param': 'curl -X POST http://your-domain/api/token/validate/?token=0c47b3d5b1aa561a5032f50e95bf069afa9a9e55', 'curl_json': 'curl -X POST -H "Content-Type: application/json" -d \'{"token":"0c47b3d5b1aa561a5032f50e95bf069afa9a9e55"}\' http://your-domain/api/token/validate/' } }, status=status.HTTP_400_BAD_REQUEST) # 验证Token validation_result = ThirdPartyAuth.validate_token(token) if not validation_result['valid']: return Response({ 'valid': False, 'error': 'Token验证失败', 'message': validation_result.get('message', 'Token无效或已过期'), 'token_preview': f"{token[:8]}..." if len(token) > 8 else token }, status=status.HTTP_401_UNAUTHORIZED) # Token有效,获取用户信息 user_name = validation_result.get('user_name') if not user_name: return Response({ 'valid': False, 'error': '用户信息获取失败', 'message': '第三方API返回的数据中没有用户名信息' }, status=status.HTTP_500_INTERNAL_SERVER_ERROR) # 检查本地是否已有用户 local_user = ThirdPartyUserManager.get_user_by_third_party_username(user_name) local_user_exists = local_user is not None return Response({ 'valid': True, 'message': 'Token验证成功', 'user_info': { 'third_party_username': user_name, 'local_user_exists': local_user_exists, 'local_username': local_user.username if local_user else None, 'local_user_id': local_user.id if local_user else None }, 'token_info': { 'token_preview': f"{token[:8]}..." if len(token) > 8 else token, 'token_length': len(token) }, 'next_steps': { 'message': '现在您可以使用此Token访问其他API接口', 'note': '如果local_user_exists为false,系统将在您首次使用其他API时自动创建本地用户账户和数据目录' } }, status=status.HTTP_200_OK) def get(self, request): """ GET方法也支持Token验证(通过URL参数) """ return self.post(request) def get_token_from_request(self, request): """ 从请求中获取Token """ # 1. 从JSON数据获取 if hasattr(request, 'data') and 'token' in request.data: return request.data.get('token') # 2. 从Authorization header获取 auth_header = request.META.get('HTTP_AUTHORIZATION', '') if auth_header.startswith('Token '): return auth_header[6:] if auth_header.startswith('Bearer '): return auth_header[7:] # 3. 从URL参数获取 token = request.GET.get('token') if token: return token # 4. 从POST form data获取 if hasattr(request, 'POST') and 'token' in request.POST: return request.POST.get('token') return None @method_decorator(csrf_exempt, name='dispatch') class UserInfoView(APIView): """ 获取当前用户信息的接口 需要有效的Token """ def get(self, request): """ 获取当前用户信息 """ # 通过认证系统已经验证了Token,用户信息在request.user中 user = request.user if not user or not user.is_authenticated: return Response({ 'error': '用户未认证', 'message': '请提供有效的Token' }, status=status.HTTP_401_UNAUTHORIZED) # 获取第三方用户映射信息 try: from api.models import ThirdPartyUserMapping mapping = ThirdPartyUserMapping.objects.get(user=user) third_party_info = { 'third_party_user_id': mapping.third_party_user_id, 'third_party_username': mapping.third_party_username, 'created_at': mapping.created_at, 'updated_at': mapping.updated_at } except ThirdPartyUserMapping.DoesNotExist: third_party_info = None # 获取用户的项目信息 projects_count = user.projects.count() return Response({ 'user_info': { 'local_user_id': user.id, 'local_username': user.username, 'email': user.email, 'first_name': user.first_name, 'last_name': user.last_name, 'date_joined': user.date_joined, 'last_login': user.last_login }, 'third_party_info': third_party_info, 'statistics': { 'projects_count': projects_count }, 'data_directories': { 'user_base_dir': f'/media/users/{user.id}/', 'projects_dir': f'/media/users/{user.id}/projects/' } }, status=status.HTTP_200_OK)