File size: 6,924 Bytes
e657e99 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 | 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) |