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

View File

@ -1,42 +1,47 @@
from rest_framework import authentication from rest_framework import authentication
from rest_framework import exceptions from rest_framework import exceptions
from django.contrib.auth.models import AnonymousUser from django.contrib.auth.models import AnonymousUser
from .models import User, UserToken from .models import User, UserToken
from django.utils import timezone from django.utils import timezone
class CustomTokenAuthentication(authentication.BaseAuthentication): class CustomTokenAuthentication(authentication.BaseAuthentication):
keyword = 'Token' # 设置认证头关键字 keyword = 'Token' # 设置认证头关键字
def authenticate(self, request): def authenticate(self, request):
# 从请求头获取token # 从请求头获取token
auth_header = request.META.get('HTTP_AUTHORIZATION') auth_header = request.META.get('HTTP_AUTHORIZATION')
if not auth_header: if not auth_header:
return None raise exceptions.AuthenticationFailed('未提供认证头')
try: try:
# 提取token # 提取token
parts = auth_header.split() parts = auth_header.split()
if len(parts) != 2 or parts[0] != self.keyword: if len(parts) != 2 or parts[0] != self.keyword:
raise exceptions.AuthenticationFailed('无效的认证头格式,应为: Token <token>') raise exceptions.AuthenticationFailed('认证头格式不正确')
token = parts[1] token = parts[1]
# 查找token记录并确保token存在且有效 # 查找token记录并确保token存在且有效
try: try:
token_obj = UserToken.objects.select_related('user').get( token_obj = UserToken.objects.select_related('user').get(
token=token, token=token,
expired_at__gt=timezone.now() # 确保token未过期 expired_at__gt=timezone.now() # 确保token未过期
) )
except UserToken.DoesNotExist: except UserToken.DoesNotExist:
raise exceptions.AuthenticationFailed('无效的token') raise exceptions.AuthenticationFailed('无效或过期的token')
# 检查用户是否激活 # 检查用户是否激活
if not token_obj.user.is_active: if not token_obj.user.is_active:
raise exceptions.AuthenticationFailed('用户已被禁用') raise exceptions.AuthenticationFailed('用户未激活')
return (token_obj.user, None) return (token_obj.user, None)
except Exception as e: except Exception as e:
raise exceptions.AuthenticationFailed(f'认证失败: {str(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 shutil
import dotenv import dotenv
import random 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 rest_framework.permissions import IsAuthenticated, AllowAny
from .authentication import CustomTokenAuthentication
import hashlib import hashlib
import time import time
from django.contrib.auth.hashers import check_password from django.contrib.auth.hashers import check_password
@ -140,6 +141,7 @@ def user_login(request):
@csrf_exempt @csrf_exempt
@api_view(['POST']) @api_view(['POST'])
@authentication_classes([CustomTokenAuthentication])
@permission_classes([IsAuthenticated]) @permission_classes([IsAuthenticated])
def update_user_info(request): def update_user_info(request):
"""更新用户信息,需要认证""" """更新用户信息,需要认证"""

View File

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