添加部分token
This commit is contained in:
parent
efafe4c452
commit
c6dbda5a88
@ -1373,7 +1373,6 @@ def get_creator_trends(request, creator_id=None):
|
|||||||
(datetime.now().date() - timedelta(days=30 - i)).strftime('%Y-%m-%d')
|
(datetime.now().date() - timedelta(days=30 - i)).strftime('%Y-%m-%d')
|
||||||
for i in range(31)
|
for i in range(31)
|
||||||
]
|
]
|
||||||
|
|
||||||
# 设定随机的起始值和波动
|
# 设定随机的起始值和波动
|
||||||
import random
|
import random
|
||||||
base_gmv = random.uniform(500, 3000)
|
base_gmv = random.uniform(500, 3000)
|
||||||
|
42
apps/user/authentication.py
Normal file
42
apps/user/authentication.py
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
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)}')
|
27
apps/user/migrations/0003_usertoken.py
Normal file
27
apps/user/migrations/0003_usertoken.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# Generated by Django 5.1.5 on 2025-05-20 03:49
|
||||||
|
|
||||||
|
import django.db.models.deletion
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('user', '0002_remove_user_is_active'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='UserToken',
|
||||||
|
fields=[
|
||||||
|
('id', models.BigAutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
|
('token', models.CharField(max_length=40, unique=True)),
|
||||||
|
('created_at', models.DateTimeField(auto_now_add=True)),
|
||||||
|
('expired_at', models.DateTimeField()),
|
||||||
|
('user', models.ForeignKey(on_delete=django.db.models.deletion.CASCADE, related_name='tokens', to='user.user')),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'db_table': 'user_token',
|
||||||
|
},
|
||||||
|
),
|
||||||
|
]
|
23
apps/user/migrations/0004_user_is_active_user_is_staff.py
Normal file
23
apps/user/migrations/0004_user_is_active_user_is_staff.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# Generated by Django 5.1.5 on 2025-05-20 03:52
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
|
dependencies = [
|
||||||
|
('user', '0003_usertoken'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='user',
|
||||||
|
name='is_active',
|
||||||
|
field=models.BooleanField(default=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='user',
|
||||||
|
name='is_staff',
|
||||||
|
field=models.BooleanField(default=False),
|
||||||
|
),
|
||||||
|
]
|
@ -1,23 +1,65 @@
|
|||||||
from django.db import models
|
from django.db import models
|
||||||
|
from django.utils import timezone
|
||||||
# Create your models here.
|
from datetime import timedelta
|
||||||
class User(models.Model):
|
from django.contrib.auth.models import AbstractBaseUser, BaseUserManager
|
||||||
"""用户模型,用于登录和账户管理"""
|
|
||||||
email = models.EmailField(max_length=255, unique=True, verbose_name="电子邮箱")
|
class UserManager(BaseUserManager):
|
||||||
password = models.CharField(max_length=255, verbose_name="密码")
|
def create_user(self, email, password=None, **extra_fields):
|
||||||
company = models.CharField(max_length=255, blank=True, null=True, verbose_name="公司名称")
|
if not email:
|
||||||
name = models.CharField(max_length=255, blank=True, null=True, verbose_name="用户姓名")
|
raise ValueError('邮箱地址不能为空')
|
||||||
is_first_login = models.BooleanField(default=True, verbose_name="是否首次登录")
|
email = self.normalize_email(email)
|
||||||
last_login = models.DateTimeField(blank=True, null=True, verbose_name="最近登录时间")
|
user = self.model(email=email, **extra_fields)
|
||||||
|
if password:
|
||||||
# 时间戳
|
user.set_password(password)
|
||||||
created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
|
user.save(using=self._db)
|
||||||
updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")
|
return user
|
||||||
|
|
||||||
class Meta:
|
class User(AbstractBaseUser):
|
||||||
verbose_name = "用户"
|
"""用户模型,用于登录和账户管理"""
|
||||||
verbose_name_plural = verbose_name
|
email = models.EmailField(max_length=255, unique=True, verbose_name="电子邮箱")
|
||||||
db_table = "users"
|
password = models.CharField(max_length=255, verbose_name="密码")
|
||||||
|
company = models.CharField(max_length=255, blank=True, null=True, verbose_name="公司名称")
|
||||||
def __str__(self):
|
name = models.CharField(max_length=255, blank=True, null=True, verbose_name="用户姓名")
|
||||||
return self.email
|
is_first_login = models.BooleanField(default=True, verbose_name="是否首次登录")
|
||||||
|
last_login = models.DateTimeField(blank=True, null=True, verbose_name="最近登录时间")
|
||||||
|
is_active = models.BooleanField(default=True)
|
||||||
|
is_staff = models.BooleanField(default=False)
|
||||||
|
|
||||||
|
# 时间戳
|
||||||
|
created_at = models.DateTimeField(auto_now_add=True, verbose_name="创建时间")
|
||||||
|
updated_at = models.DateTimeField(auto_now=True, verbose_name="更新时间")
|
||||||
|
|
||||||
|
objects = UserManager()
|
||||||
|
|
||||||
|
USERNAME_FIELD = 'email'
|
||||||
|
REQUIRED_FIELDS = []
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
verbose_name = "用户"
|
||||||
|
verbose_name_plural = verbose_name
|
||||||
|
db_table = "users"
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return self.email
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_authenticated(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
class UserToken(models.Model):
|
||||||
|
user = models.ForeignKey(User, on_delete=models.CASCADE, related_name='tokens')
|
||||||
|
token = models.CharField(max_length=40, unique=True)
|
||||||
|
created_at = models.DateTimeField(auto_now_add=True)
|
||||||
|
expired_at = models.DateTimeField()
|
||||||
|
|
||||||
|
def save(self, *args, **kwargs):
|
||||||
|
if not self.expired_at:
|
||||||
|
# 设置token有效期为30天
|
||||||
|
self.expired_at = timezone.now() + timedelta(days=30)
|
||||||
|
super().save(*args, **kwargs)
|
||||||
|
|
||||||
|
def is_expired(self):
|
||||||
|
return timezone.now() > self.expired_at
|
||||||
|
|
||||||
|
class Meta:
|
||||||
|
db_table = 'user_token'
|
||||||
|
@ -1,268 +1,281 @@
|
|||||||
from django.http import JsonResponse
|
from django.http import JsonResponse
|
||||||
# from .models import TiktokUserVideos
|
# 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
|
||||||
from django.views.decorators.csrf import csrf_exempt
|
from django.views.decorators.csrf import csrf_exempt
|
||||||
from django.shortcuts import render
|
from django.shortcuts import render
|
||||||
import json
|
import json
|
||||||
import requests
|
import requests
|
||||||
import concurrent.futures
|
import concurrent.futures
|
||||||
import shutil
|
import shutil
|
||||||
import dotenv
|
import dotenv
|
||||||
import random
|
import random
|
||||||
|
from rest_framework.decorators import api_view, permission_classes
|
||||||
dotenv.load_dotenv()
|
from rest_framework.permissions import IsAuthenticated, AllowAny
|
||||||
|
import hashlib
|
||||||
# 添加logger定义
|
import time
|
||||||
logger = logging.getLogger(__name__)
|
from django.contrib.auth.hashers import check_password
|
||||||
|
from django.utils import timezone
|
||||||
directory_monitoring = {}
|
|
||||||
|
dotenv.load_dotenv()
|
||||||
# 全局变量来控制检测线程
|
|
||||||
monitor_thread = None
|
# 添加logger定义
|
||||||
is_monitoring = False
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@csrf_exempt
|
directory_monitoring = {}
|
||||||
@require_http_methods(["POST"])
|
|
||||||
def user_login(request):
|
# 全局变量来控制检测线程
|
||||||
"""用户登录接口,首次登录会返回需要填写信息的标志"""
|
monitor_thread = None
|
||||||
try:
|
is_monitoring = False
|
||||||
from .models import User
|
|
||||||
import json
|
def generate_token(user_id):
|
||||||
from django.contrib.auth.hashers import check_password, make_password
|
"""生成简单的token"""
|
||||||
from datetime import datetime
|
# 使用用户ID和当前时间戳生成token
|
||||||
|
token_string = f"{user_id}:{time.time()}"
|
||||||
data = json.loads(request.body)
|
return hashlib.sha1(token_string.encode()).hexdigest()
|
||||||
|
|
||||||
# 获取登录参数
|
def create_user_token(user):
|
||||||
email = data.get('email')
|
"""创建并保存用户token"""
|
||||||
password = data.get('password')
|
from .models import UserToken
|
||||||
|
# 删除该用户的所有旧token
|
||||||
if not email or not password:
|
UserToken.objects.filter(user=user).delete()
|
||||||
return JsonResponse({
|
# 生成新token
|
||||||
'code': 400,
|
token = generate_token(user.id)
|
||||||
'message': '缺少必要参数: email 或 password',
|
# 保存到数据库
|
||||||
'data': None
|
user_token = UserToken.objects.create(
|
||||||
}, json_dumps_params={'ensure_ascii': False})
|
user=user,
|
||||||
|
token=token
|
||||||
# 查询用户
|
)
|
||||||
try:
|
return token
|
||||||
user = User.objects.get(email=email)
|
|
||||||
|
@csrf_exempt
|
||||||
# 验证密码
|
@api_view(['POST'])
|
||||||
# 注意:这里假设密码已经进行了哈希存储,实际使用时需要采用适当的密码验证方法
|
@permission_classes([AllowAny])
|
||||||
# 如果密码未哈希存储,直接比较原始密码
|
def user_login(request):
|
||||||
password_valid = (user.password == password)
|
"""
|
||||||
|
用户登录接口
|
||||||
if not password_valid:
|
|
||||||
return JsonResponse({
|
返回的 token 使用格式:
|
||||||
'code': 401,
|
在请求头中添加:
|
||||||
'message': '用户名或密码错误',
|
Authorization: Token <your_token>
|
||||||
'data': None
|
|
||||||
}, json_dumps_params={'ensure_ascii': False})
|
例如:
|
||||||
|
Authorization: Token fa6931ec4cf5bd46d8dc3a671fe9862c467426b3
|
||||||
# 检查是否首次登录
|
"""
|
||||||
is_first_login = user.is_first_login
|
try:
|
||||||
|
from .models import User
|
||||||
# 更新最后登录时间
|
import json
|
||||||
user.last_login = datetime.now()
|
from django.contrib.auth.hashers import check_password
|
||||||
user.save()
|
from datetime import datetime
|
||||||
|
|
||||||
# 构造返回数据
|
data = json.loads(request.body)
|
||||||
user_data = {
|
|
||||||
'user_id': user.id,
|
# 获取登录参数
|
||||||
'email': user.email,
|
email = data.get('email')
|
||||||
'is_first_login': is_first_login,
|
password = data.get('password')
|
||||||
'name': user.name,
|
|
||||||
'company': user.company
|
if not email or not password:
|
||||||
}
|
return JsonResponse({
|
||||||
|
'code': 400,
|
||||||
return JsonResponse({
|
'message': '缺少必要参数: email 或 password',
|
||||||
'code': 200,
|
'data': None
|
||||||
'message': '登录成功',
|
}, json_dumps_params={'ensure_ascii': False})
|
||||||
'data': user_data
|
|
||||||
}, json_dumps_params={'ensure_ascii': False})
|
# 查询用户
|
||||||
|
try:
|
||||||
except User.DoesNotExist:
|
user = User.objects.get(email=email)
|
||||||
# 用户不存在,创建新用户
|
|
||||||
new_user = User.objects.create(
|
# 验证密码
|
||||||
email=email,
|
if not user.check_password(password):
|
||||||
password=password, # 注意:实际使用时应该哈希存储密码
|
return JsonResponse({
|
||||||
is_first_login=True,
|
'code': 401,
|
||||||
last_login=datetime.now()
|
'message': '用户名或密码错误',
|
||||||
)
|
'data': None
|
||||||
|
}, json_dumps_params={'ensure_ascii': False})
|
||||||
return JsonResponse({
|
|
||||||
'code': 200,
|
# 生成并保存token
|
||||||
'message': '登录成功',
|
token = create_user_token(user)
|
||||||
'data': {
|
|
||||||
'user_id': new_user.id,
|
# 检查是否首次登录
|
||||||
'email': new_user.email,
|
is_first_login = user.is_first_login
|
||||||
'is_first_login': True,
|
|
||||||
'name': None,
|
# 更新最后登录时间
|
||||||
'company': None
|
user.last_login = timezone.now()
|
||||||
}
|
user.save()
|
||||||
}, json_dumps_params={'ensure_ascii': False})
|
|
||||||
|
# 构造返回数据
|
||||||
except Exception as e:
|
user_data = {
|
||||||
logger.error(f"用户登录失败: {e}")
|
'user_id': user.id,
|
||||||
import traceback
|
'email': user.email,
|
||||||
logger.error(f"详细错误: {traceback.format_exc()}")
|
'is_first_login': is_first_login,
|
||||||
return JsonResponse({
|
'name': user.name,
|
||||||
'code': 500,
|
'company': user.company,
|
||||||
'message': f'登录失败: {str(e)}',
|
'token': token
|
||||||
'data': None
|
}
|
||||||
}, json_dumps_params={'ensure_ascii': False})
|
|
||||||
|
return JsonResponse({
|
||||||
|
'code': 200,
|
||||||
@csrf_exempt
|
'message': '登录成功',
|
||||||
@require_http_methods(["POST"])
|
'data': user_data
|
||||||
def update_user_info(request):
|
}, json_dumps_params={'ensure_ascii': False})
|
||||||
"""更新用户信息,首次登录时填写公司和姓名"""
|
|
||||||
try:
|
except User.DoesNotExist:
|
||||||
from .models import User
|
return JsonResponse({
|
||||||
import json
|
'code': 404,
|
||||||
|
'message': '用户不存在',
|
||||||
data = json.loads(request.body)
|
'data': None
|
||||||
|
}, json_dumps_params={'ensure_ascii': False})
|
||||||
# 获取参数
|
|
||||||
user_id = data.get('user_id')
|
except Exception as e:
|
||||||
company = data.get('company')
|
logger.error(f"用户登录失败: {e}")
|
||||||
name = data.get('name')
|
import traceback
|
||||||
|
logger.error(f"详细错误: {traceback.format_exc()}")
|
||||||
if not user_id:
|
return JsonResponse({
|
||||||
return JsonResponse({
|
'code': 500,
|
||||||
'code': 400,
|
'message': f'登录失败: {str(e)}',
|
||||||
'message': '缺少必要参数: user_id',
|
'data': None
|
||||||
'data': None
|
}, json_dumps_params={'ensure_ascii': False})
|
||||||
}, json_dumps_params={'ensure_ascii': False})
|
|
||||||
|
|
||||||
# 如果是首次登录,需要填写公司和姓名
|
@csrf_exempt
|
||||||
if not company or not name:
|
@api_view(['POST'])
|
||||||
return JsonResponse({
|
@permission_classes([IsAuthenticated])
|
||||||
'code': 400,
|
def update_user_info(request):
|
||||||
'message': '首次登录需要填写公司和姓名',
|
"""更新用户信息,需要认证"""
|
||||||
'data': None
|
try:
|
||||||
}, json_dumps_params={'ensure_ascii': False})
|
data = json.loads(request.body)
|
||||||
|
|
||||||
# 查询用户并更新信息
|
# 获取参数
|
||||||
try:
|
company = data.get('company')
|
||||||
user = User.objects.get(id=user_id)
|
name = data.get('name')
|
||||||
|
|
||||||
# 更新信息
|
# 获取当前认证用户
|
||||||
user.company = company
|
user = request.user
|
||||||
user.name = name
|
|
||||||
user.is_first_login = False # 更新后不再是首次登录
|
# 如果请求中包含 user_id 且与当前用户不匹配,返回错误
|
||||||
user.save()
|
if 'user_id' in data and int(data['user_id']) != user.id:
|
||||||
|
return JsonResponse({
|
||||||
return JsonResponse({
|
'code': 403,
|
||||||
'code': 200,
|
'message': '您只能修改自己的信息',
|
||||||
'message': '信息更新成功',
|
'data': None
|
||||||
'data': {
|
}, json_dumps_params={'ensure_ascii': False})
|
||||||
'user_id': user.id,
|
|
||||||
'email': user.email,
|
# 如果是首次登录,需要填写公司和姓名
|
||||||
'is_first_login': False,
|
if not company or not name:
|
||||||
'name': user.name,
|
return JsonResponse({
|
||||||
'company': user.company
|
'code': 400,
|
||||||
}
|
'message': '首次登录需要填写公司和姓名',
|
||||||
}, json_dumps_params={'ensure_ascii': False})
|
'data': None
|
||||||
|
}, json_dumps_params={'ensure_ascii': False})
|
||||||
except User.DoesNotExist:
|
|
||||||
return JsonResponse({
|
# 更新信息
|
||||||
'code': 404,
|
user.company = company
|
||||||
'message': f'找不到ID为 {user_id} 的用户',
|
user.name = name
|
||||||
'data': None
|
user.is_first_login = False # 更新后不再是首次登录
|
||||||
}, json_dumps_params={'ensure_ascii': False})
|
user.save()
|
||||||
|
|
||||||
except Exception as e:
|
return JsonResponse({
|
||||||
logger.error(f"更新用户信息失败: {e}")
|
'code': 200,
|
||||||
import traceback
|
'message': '信息更新成功',
|
||||||
logger.error(f"详细错误: {traceback.format_exc()}")
|
'data': {
|
||||||
return JsonResponse({
|
'user_id': user.id,
|
||||||
'code': 500,
|
'email': user.email,
|
||||||
'message': f'更新用户信息失败: {str(e)}',
|
'is_first_login': False,
|
||||||
'data': None
|
'name': user.name,
|
||||||
}, json_dumps_params={'ensure_ascii': False})
|
'company': user.company
|
||||||
|
}
|
||||||
|
}, json_dumps_params={'ensure_ascii': False})
|
||||||
@csrf_exempt
|
|
||||||
@require_http_methods(["POST"])
|
except Exception as e:
|
||||||
def user_register(request):
|
logger.error(f"更新用户信息失败: {e}")
|
||||||
"""用户注册接口,允许用户创建新账户,可选填写公司和姓名"""
|
import traceback
|
||||||
try:
|
logger.error(f"详细错误: {traceback.format_exc()}")
|
||||||
from .models import User
|
return JsonResponse({
|
||||||
import json
|
'code': 500,
|
||||||
from datetime import datetime
|
'message': f'更新用户信息失败: {str(e)}',
|
||||||
|
'data': None
|
||||||
data = json.loads(request.body)
|
}, json_dumps_params={'ensure_ascii': False})
|
||||||
|
|
||||||
# 获取注册参数
|
|
||||||
email = data.get('email')
|
@csrf_exempt
|
||||||
password = data.get('password')
|
@api_view(['POST'])
|
||||||
company = data.get('company') # 可选参数
|
@permission_classes([AllowAny])
|
||||||
name = data.get('name') # 可选参数
|
def user_register(request):
|
||||||
|
"""用户注册接口"""
|
||||||
# 检查必要参数
|
try:
|
||||||
if not email or not password:
|
from .models import User
|
||||||
return JsonResponse({
|
import json
|
||||||
'code': 400,
|
from datetime import datetime
|
||||||
'message': '缺少必要参数: email 或 password',
|
|
||||||
'data': None
|
data = json.loads(request.body)
|
||||||
}, json_dumps_params={'ensure_ascii': False})
|
|
||||||
|
# 获取注册参数
|
||||||
# 检查邮箱是否已注册
|
email = data.get('email')
|
||||||
if User.objects.filter(email=email).exists():
|
password = data.get('password')
|
||||||
return JsonResponse({
|
company = data.get('company') # 可选参数
|
||||||
'code': 409,
|
name = data.get('name') # 可选参数
|
||||||
'message': '该邮箱已注册',
|
|
||||||
'data': None
|
# 检查必要参数
|
||||||
}, json_dumps_params={'ensure_ascii': False})
|
if not email or not password:
|
||||||
|
return JsonResponse({
|
||||||
# 创建用户
|
'code': 400,
|
||||||
try:
|
'message': '缺少必要参数: email 或 password',
|
||||||
# 根据是否提供公司和姓名决定是否为首次登录
|
'data': None
|
||||||
is_first_login = not (company and name)
|
}, json_dumps_params={'ensure_ascii': False})
|
||||||
|
|
||||||
# 创建用户
|
# 检查邮箱是否已注册
|
||||||
user = User.objects.create(
|
if User.objects.filter(email=email).exists():
|
||||||
email=email,
|
return JsonResponse({
|
||||||
password=password, # 注意:实际使用时应该哈希存储密码
|
'code': 409,
|
||||||
company=company,
|
'message': '该邮箱已注册',
|
||||||
name=name,
|
'data': None
|
||||||
is_first_login=is_first_login,
|
}, json_dumps_params={'ensure_ascii': False})
|
||||||
last_login=datetime.now()
|
|
||||||
)
|
# 创建用户
|
||||||
|
try:
|
||||||
# 构造返回数据
|
# 根据是否提供公司和姓名决定是否为首次登录
|
||||||
user_data = {
|
is_first_login = not (company and name)
|
||||||
'user_id': user.id,
|
|
||||||
'email': user.email,
|
# 创建用户
|
||||||
'is_first_login': is_first_login,
|
user = User.objects.create_user(
|
||||||
'company': user.company,
|
email=email,
|
||||||
'name': user.name
|
password=password,
|
||||||
}
|
company=company,
|
||||||
|
name=name,
|
||||||
return JsonResponse({
|
is_first_login=is_first_login,
|
||||||
'code': 200,
|
last_login=timezone.now()
|
||||||
'message': '注册成功',
|
)
|
||||||
'data': user_data
|
|
||||||
}, json_dumps_params={'ensure_ascii': False})
|
# 构造返回数据
|
||||||
|
user_data = {
|
||||||
except Exception as e:
|
'user_id': user.id,
|
||||||
logger.error(f"创建用户失败: {e}")
|
'email': user.email,
|
||||||
return JsonResponse({
|
'is_first_login': is_first_login,
|
||||||
'code': 500,
|
'company': user.company,
|
||||||
'message': f'注册失败: {str(e)}',
|
'name': user.name
|
||||||
'data': None
|
}
|
||||||
}, json_dumps_params={'ensure_ascii': False})
|
|
||||||
|
return JsonResponse({
|
||||||
except Exception as e:
|
'code': 200,
|
||||||
logger.error(f"用户注册失败: {e}")
|
'message': '注册成功',
|
||||||
import traceback
|
'data': user_data
|
||||||
logger.error(f"详细错误: {traceback.format_exc()}")
|
}, json_dumps_params={'ensure_ascii': False})
|
||||||
return JsonResponse({
|
|
||||||
'code': 500,
|
except Exception as e:
|
||||||
'message': f'注册失败: {str(e)}',
|
logger.error(f"创建用户失败: {e}")
|
||||||
'data': None
|
return JsonResponse({
|
||||||
}, json_dumps_params={'ensure_ascii': False})
|
'code': 500,
|
||||||
|
'message': f'注册失败: {str(e)}',
|
||||||
|
'data': None
|
||||||
|
}, json_dumps_params={'ensure_ascii': False})
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
logger.error(f"用户注册失败: {e}")
|
||||||
|
import traceback
|
||||||
|
logger.error(f"详细错误: {traceback.format_exc()}")
|
||||||
|
return JsonResponse({
|
||||||
|
'code': 500,
|
||||||
|
'message': f'注册失败: {str(e)}',
|
||||||
|
'data': None
|
||||||
|
}, json_dumps_params={'ensure_ascii': False})
|
||||||
|
@ -44,7 +44,8 @@ INSTALLED_APPS = [
|
|||||||
"apps.discovery.apps.DiscoveryConfig",
|
"apps.discovery.apps.DiscoveryConfig",
|
||||||
"apps.template.apps.TemplateConfig",
|
"apps.template.apps.TemplateConfig",
|
||||||
"apps.brands.apps.BrandsConfig",
|
"apps.brands.apps.BrandsConfig",
|
||||||
|
'rest_framework',
|
||||||
|
'rest_framework_simplejwt',
|
||||||
]
|
]
|
||||||
|
|
||||||
MIDDLEWARE = [
|
MIDDLEWARE = [
|
||||||
@ -173,4 +174,34 @@ LOGGING = {
|
|||||||
'propagate': True,
|
'propagate': True,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# 自定义用户模型
|
||||||
|
AUTH_USER_MODEL = 'user.User'
|
||||||
|
|
||||||
|
# REST Framework 设置
|
||||||
|
REST_FRAMEWORK = {
|
||||||
|
'DEFAULT_AUTHENTICATION_CLASSES': (
|
||||||
|
'apps.user.authentication.CustomTokenAuthentication',
|
||||||
|
),
|
||||||
|
}
|
||||||
|
|
||||||
|
# JWT 设置
|
||||||
|
from datetime import timedelta
|
||||||
|
SIMPLE_JWT = {
|
||||||
|
'ACCESS_TOKEN_LIFETIME': timedelta(days=1),
|
||||||
|
'REFRESH_TOKEN_LIFETIME': timedelta(days=7),
|
||||||
|
'ROTATE_REFRESH_TOKENS': False,
|
||||||
|
'ALGORITHM': 'HS256',
|
||||||
|
'SIGNING_KEY': SECRET_KEY,
|
||||||
|
'AUTH_HEADER_TYPES': ('Bearer',),
|
||||||
|
'USER_ID_FIELD': 'id',
|
||||||
|
'USER_ID_CLAIM': 'user_id',
|
||||||
|
'UPDATE_LAST_LOGIN': False, # 不在 token 中记录最后登录时间
|
||||||
|
'TOKEN_TYPE_CLAIM': None, # 不在 token 中包含 token 类型
|
||||||
|
'JTI_CLAIM': None, # 不在 token 中包含 JWT ID
|
||||||
|
}
|
||||||
|
|
||||||
|
# JWT配置
|
||||||
|
JWT_SECRET_KEY = 'your-secret-key-here' # 建议使用更安全的密钥
|
||||||
|
JWT_EXPIRATION_DELTA = 24 * 60 * 60 # token有效期24小时(秒)
|
@ -1,8 +1,14 @@
|
|||||||
from django.contrib import admin
|
from django.contrib import admin
|
||||||
from django.urls import path, include
|
from django.urls import path, include
|
||||||
|
from rest_framework_simplejwt.views import (
|
||||||
|
TokenObtainPairView,
|
||||||
|
TokenRefreshView,
|
||||||
|
)
|
||||||
|
|
||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
|
path('api/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
|
||||||
|
path('api/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
|
||||||
path('api/user/', include('apps.user.urls')),
|
path('api/user/', include('apps.user.urls')),
|
||||||
path('api/daren_detail/', include('apps.daren_detail.urls')),
|
path('api/daren_detail/', include('apps.daren_detail.urls')),
|
||||||
path('api/operation/', include('apps.expertproducts.urls')),
|
path('api/operation/', include('apps.expertproducts.urls')),
|
||||||
|
Loading…
Reference in New Issue
Block a user