添加token

This commit is contained in:
jlj 2025-05-20 15:58:53 +08:00
parent c266fb3efd
commit db697fae26
4 changed files with 116 additions and 61 deletions

View File

@ -1,5 +1,4 @@
from django.http import JsonResponse
# from .models import TiktokUserVideos
import logging
import os
from django.views.decorators.http import require_http_methods
@ -13,6 +12,15 @@ import dotenv
import random
import uuid
from django.db.models import Q
from rest_framework.decorators import api_view, authentication_classes
from apps.user.authentication import CustomTokenAuthentication
from rest_framework.response import Response
from .models import (
CreatorProfile, BrandCampaign, CreatorCampaign,
CollaborationMetrics, VideoMetrics, LiveMetrics,
FollowerMetrics, TrendMetrics, CreatorVideo
)
from apps.brands.models import Campaign, Brand
dotenv.load_dotenv()
@ -26,12 +34,13 @@ monitor_thread = None
is_monitoring = False
@api_view(['POST'])
@authentication_classes([CustomTokenAuthentication])
@csrf_exempt
@require_http_methods(["POST"])
def filter_creators(request):
"""根据过滤条件筛选达人信息POST版"""
try:
from .models import CreatorProfile
import json
# 解析POST请求体
@ -205,12 +214,13 @@ def filter_creators(request):
}, json_dumps_params={'ensure_ascii': False})
@api_view(['POST'])
@authentication_classes([CustomTokenAuthentication])
@csrf_exempt
@require_http_methods(["POST"])
def add_creator(request):
"""添加或更新达人信息"""
try:
from .models import CreatorProfile
import json
data = json.loads(request.body)
@ -281,7 +291,7 @@ def add_creator(request):
creator.collab_count = data.get('collab_count', creator.collab_count)
creator.latest_collab = data.get('latest_collab', creator.latest_collab)
creator.e_commerce_platforms = data.get('e_commerce_platforms', creator.e_commerce_platforms)
creator.is_active = data.get('is_active', creator.is_active)
# creator.is_active = data.get('is_active', creator.is_active)
creator.mcn = data.get('mcn', creator.mcn)
# 保存更新
@ -307,6 +317,8 @@ def add_creator(request):
}, json_dumps_params={'ensure_ascii': False})
@api_view(['GET'])
@authentication_classes([CustomTokenAuthentication])
@csrf_exempt
@require_http_methods(["GET"])
def get_campaigns(request):
@ -349,6 +361,8 @@ def get_campaigns(request):
}, json_dumps_params={'ensure_ascii': False})
@api_view(['POST'])
@authentication_classes([CustomTokenAuthentication])
@csrf_exempt
@require_http_methods(["POST"])
def add_to_campaign(request):
@ -446,11 +460,13 @@ def add_to_campaign(request):
}, json_dumps_params={'ensure_ascii': False})
@api_view(['GET'])
@authentication_classes([CustomTokenAuthentication])
@csrf_exempt
@require_http_methods(["GET"])
def get_creator_detail(request, creator_id):
"""获取达人详情信息"""
try:
from .models import CreatorProfile
import json
# 查询指定ID的达人信息
@ -555,12 +571,13 @@ def get_creator_detail(request, creator_id):
}, json_dumps_params={'ensure_ascii': False})
@api_view(['POST'])
@authentication_classes([CustomTokenAuthentication])
@csrf_exempt
@require_http_methods(["POST"])
def update_creator_detail(request):
"""更新达人详细信息"""
try:
from .models import CreatorProfile
import json
data = json.loads(request.body)
@ -624,12 +641,14 @@ def update_creator_detail(request):
# 获取特定达人与各品牌的合作详情
@api_view(['GET'])
@authentication_classes([CustomTokenAuthentication])
@csrf_exempt
@require_http_methods(["GET"])
def get_creator_brand_campaigns(request, creator_id=None):
"""获取特定达人与各品牌的合作详情"""
try:
from .models import CreatorProfile, BrandCampaign, CreatorCampaign, Campaign
import json
# 检查creator_id是否提供
if not creator_id:
@ -674,7 +693,8 @@ def get_creator_brand_campaigns(request, creator_id=None):
if not brand_campaigns_with_campaign.exists():
# 获取所有相关Campaign的品牌首字母
campaigns = Campaign.objects.filter(id__in=campaign_ids)
brands_needed = [campaign.brand[:1].upper() for campaign in campaigns if campaign.brand]
brands_needed = [campaign.brand.name[:1].upper() if isinstance(campaign.brand, Brand) else campaign.brand[:1].upper()
for campaign in campaigns if campaign.brand]
# 合并品牌活动数据
campaign_list = []
@ -747,7 +767,8 @@ def get_creator_brand_campaigns(request, creator_id=None):
# 为每个CreatorCampaign创建一个默认的活动数据
for cc in creator_campaigns:
campaign = cc.campaign
brand_id = campaign.brand[:1].upper() if campaign.brand else 'U'
# 修改获取brand_id的逻辑
brand_id = campaign.brand.name[:1].upper() if isinstance(campaign.brand, Brand) else (campaign.brand[:1].upper() if campaign.brand else 'U')
# 为不同品牌设置不同颜色
colors = {
@ -762,7 +783,7 @@ def get_creator_brand_campaigns(request, creator_id=None):
campaign_data = {
"brand": {
"id": brand_id,
"name": campaign.brand or "brand",
"name": campaign.brand.name if isinstance(campaign.brand, Brand) else (campaign.brand or "brand"),
"color": colors.get(brand_id, '#000000')
},
"pricing_detail": "$80", # 默认价格
@ -828,12 +849,13 @@ def get_creator_brand_campaigns(request, creator_id=None):
# 获取创作者的协作指标、视频和直播指标数据
@api_view(['GET'])
@authentication_classes([CustomTokenAuthentication])
@csrf_exempt
@require_http_methods(["GET"])
def get_creator_metrics(request, creator_id):
"""获取创作者的协作指标、视频和直播指标数据"""
try:
from .models import CreatorProfile, CollaborationMetrics, VideoMetrics, LiveMetrics
import json
from datetime import datetime
@ -999,12 +1021,13 @@ def get_creator_metrics(request, creator_id):
# 更新创作者的指标数据
@api_view(['POST'])
@authentication_classes([CustomTokenAuthentication])
@csrf_exempt
@require_http_methods(["POST"])
def update_creator_metrics(request):
"""更新创作者的指标数据"""
try:
from .models import CreatorProfile, CollaborationMetrics, VideoMetrics, LiveMetrics
import json
from datetime import datetime
@ -1209,12 +1232,13 @@ def update_creator_metrics(request):
}, json_dumps_params={'ensure_ascii': False})
@api_view(['GET'])
@authentication_classes([CustomTokenAuthentication])
@csrf_exempt
@require_http_methods(["GET"])
def get_creator_followers_metrics(request, creator_id=None):
"""获取创作者的粉丝统计指标数据"""
try:
from .models import CreatorProfile, FollowerMetrics
import json
from datetime import datetime
@ -1307,12 +1331,13 @@ def get_creator_followers_metrics(request, creator_id=None):
}, json_dumps_params={'ensure_ascii': False})
@api_view(['GET'])
@authentication_classes([CustomTokenAuthentication])
@csrf_exempt
@require_http_methods(["GET"])
def get_creator_trends(request, creator_id=None):
"""获取创作者的趋势指标数据"""
try:
from .models import CreatorProfile, TrendMetrics
import json
from datetime import datetime, timedelta
@ -1458,12 +1483,13 @@ def get_creator_trends(request, creator_id=None):
}, json_dumps_params={'ensure_ascii': False})
@api_view(['POST'])
@authentication_classes([CustomTokenAuthentication])
@csrf_exempt
@require_http_methods(["POST"])
def update_creator_followers(request):
"""更新创作者的粉丝统计数据"""
try:
from .models import CreatorProfile, FollowerMetrics
import json
from datetime import datetime
@ -1565,12 +1591,13 @@ def update_creator_followers(request):
}, json_dumps_params={'ensure_ascii': False})
@api_view(['POST'])
@authentication_classes([CustomTokenAuthentication])
@csrf_exempt
@require_http_methods(["POST"])
def update_creator_trend(request):
"""更新创作者的趋势数据"""
try:
from .models import CreatorProfile, TrendMetrics
import json
from datetime import datetime
@ -1649,12 +1676,13 @@ def update_creator_trend(request):
}, json_dumps_params={'ensure_ascii': False})
@api_view(['GET'])
@authentication_classes([CustomTokenAuthentication])
@csrf_exempt
@require_http_methods(["GET"])
def get_creator_videos(request, creator_id=None):
"""获取创作者的视频列表,分为普通视频和带产品视频"""
try:
from .models import CreatorProfile, CreatorVideo
import json
from datetime import datetime
@ -1850,12 +1878,13 @@ def get_creator_videos(request, creator_id=None):
}, json_dumps_params={'ensure_ascii': False})
@api_view(['POST'])
@authentication_classes([CustomTokenAuthentication])
@csrf_exempt
@require_http_methods(["POST"])
def add_creator_video(request):
"""添加创作者视频"""
try:
from .models import CreatorProfile, CreatorVideo
import json
from datetime import datetime
@ -1956,6 +1985,8 @@ def add_creator_video(request):
######################################## 公有达人和私有达人 ########################################
@api_view(['GET'])
@authentication_classes([CustomTokenAuthentication])
@csrf_exempt
@require_http_methods(["GET"])
def get_public_creators(request):
@ -2065,6 +2096,8 @@ def get_public_creators(request):
}, json_dumps_params={'ensure_ascii': False})
@api_view(['POST'])
@authentication_classes([CustomTokenAuthentication])
@csrf_exempt
@require_http_methods(["POST"])
def add_to_public_pool(request):
@ -2144,6 +2177,8 @@ def add_to_public_pool(request):
}, json_dumps_params={'ensure_ascii': False})
@api_view(['GET'])
@authentication_classes([CustomTokenAuthentication])
@csrf_exempt
@require_http_methods(["GET"])
def get_private_pools(request):
@ -2197,6 +2232,8 @@ def get_private_pools(request):
}, json_dumps_params={'ensure_ascii': False})
@api_view(['POST'])
@authentication_classes([CustomTokenAuthentication])
@csrf_exempt
@require_http_methods(["POST"])
def create_private_pool(request):
@ -2306,6 +2343,8 @@ def create_private_pool(request):
}, json_dumps_params={'ensure_ascii': False})
@api_view(['GET'])
@authentication_classes([CustomTokenAuthentication])
@csrf_exempt
@require_http_methods(["GET"])
def get_private_pool_creators(request, pool_id=None):
@ -2452,6 +2491,8 @@ def get_private_pool_creators(request, pool_id=None):
}, json_dumps_params={'ensure_ascii': False})
@api_view(['POST'])
@authentication_classes([CustomTokenAuthentication])
@csrf_exempt
@require_http_methods(["POST"])
def add_creator_to_private_pool(request):
@ -2574,6 +2615,8 @@ def add_creator_to_private_pool(request):
}, json_dumps_params={'ensure_ascii': False})
@api_view(['POST'])
@authentication_classes([CustomTokenAuthentication])
@csrf_exempt
@require_http_methods(["POST"])
def update_creator_in_private_pool(request):
@ -2638,6 +2681,8 @@ def update_creator_in_private_pool(request):
}, json_dumps_params={'ensure_ascii': False})
@api_view(['POST'])
@authentication_classes([CustomTokenAuthentication])
@csrf_exempt
@require_http_methods(["POST"])
def remove_creator_from_private_pool(request):

View File

@ -1,42 +1,47 @@
from rest_framework import authentication
from rest_framework import exceptions
from django.contrib.auth.models import AnonymousUser
from .models import User, UserToken
from django.utils import timezone
class CustomTokenAuthentication(authentication.BaseAuthentication):
keyword = 'Token' # 设置认证头关键字
def authenticate(self, request):
# 从请求头获取token
auth_header = request.META.get('HTTP_AUTHORIZATION')
if not auth_header:
return None
try:
# 提取token
parts = auth_header.split()
if len(parts) != 2 or parts[0] != self.keyword:
raise exceptions.AuthenticationFailed('无效的认证头格式,应为: Token <token>')
token = parts[1]
# 查找token记录并确保token存在且有效
try:
token_obj = UserToken.objects.select_related('user').get(
token=token,
expired_at__gt=timezone.now() # 确保token未过期
)
except UserToken.DoesNotExist:
raise exceptions.AuthenticationFailed('无效的token')
# 检查用户是否激活
if not token_obj.user.is_active:
raise exceptions.AuthenticationFailed('用户已被禁用')
return (token_obj.user, None)
except Exception as e:
raise exceptions.AuthenticationFailed(f'认证失败: {str(e)}')
from rest_framework import authentication
from rest_framework import exceptions
from django.contrib.auth.models import AnonymousUser
from .models import User, UserToken
from django.utils import timezone
class CustomTokenAuthentication(authentication.BaseAuthentication):
keyword = 'Token' # 设置认证头关键字
def authenticate(self, request):
# 从请求头获取token
auth_header = request.META.get('HTTP_AUTHORIZATION')
if not auth_header:
raise exceptions.AuthenticationFailed('未提供认证头')
try:
# 提取token
parts = auth_header.split()
if len(parts) != 2 or parts[0] != self.keyword:
raise exceptions.AuthenticationFailed('认证头格式不正确')
token = parts[1]
# 查找token记录并确保token存在且有效
try:
token_obj = UserToken.objects.select_related('user').get(
token=token,
expired_at__gt=timezone.now() # 确保token未过期
)
except UserToken.DoesNotExist:
raise exceptions.AuthenticationFailed('无效或过期的token')
# 检查用户是否激活
if not token_obj.user.is_active:
raise exceptions.AuthenticationFailed('用户未激活')
return (token_obj.user, None)
except Exception as e:
if isinstance(e, exceptions.AuthenticationFailed):
raise e
raise exceptions.AuthenticationFailed('认证失败')
def authenticate_header(self, request):
return self.keyword

View File

@ -11,8 +11,9 @@ import concurrent.futures
import shutil
import dotenv
import random
from rest_framework.decorators import api_view, permission_classes
from rest_framework.decorators import api_view, permission_classes, authentication_classes
from rest_framework.permissions import IsAuthenticated, AllowAny
from .authentication import CustomTokenAuthentication
import hashlib
import time
from django.contrib.auth.hashers import check_password
@ -140,6 +141,7 @@ def user_login(request):
@csrf_exempt
@api_view(['POST'])
@authentication_classes([CustomTokenAuthentication])
@permission_classes([IsAuthenticated])
def update_user_info(request):
"""更新用户信息,需要认证"""

View File

@ -205,6 +205,9 @@ REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'apps.user.authentication.CustomTokenAuthentication',
),
'UNAUTHENTICATED_USER': None,
'DEFAULT_PERMISSION_CLASSES': [], # 默认不需要任何权限
'DEFAULT_AUTHENTICATION_CLASSES': [] # 默认不需要任何认证
}
# JWT 设置