diff --git a/backend/system/tasks.py b/backend/system/tasks.py index 535fb62..2b0a603 100644 --- a/backend/system/tasks.py +++ b/backend/system/tasks.py @@ -1,7 +1,6 @@ import requests from celery import shared_task -from django.utils import timezone from system.models import LoginLog, User @@ -10,23 +9,14 @@ def add(x, y): return x + y - @shared_task -def update_user_login_info(user_id, client_ip, user_agent): - # 更新用户登录信息 - user = User.objects.get(id=user_id) - user.login_ip = client_ip - user.last_login = timezone.now() - user.save(update_fields=['login_ip', 'last_login']) - +def update_user_login_info(username, client_ip, user_agent, result): # 获取地理位置信息 location_info = get_location_from_ip(client_ip) - # location_info = None - # 记录登录日录 LoginLog.objects.create( - username=user.username, - result=LoginLog.LoginResult.SUCCESS, + username=username, + result=result, user_ip=client_ip, location=location_info, user_agent=user_agent diff --git a/backend/system/views/user.py b/backend/system/views/user.py index cec84a1..0f8fa2c 100644 --- a/backend/system/views/user.py +++ b/backend/system/views/user.py @@ -1,15 +1,17 @@ import requests -from rest_framework import serializers +from rest_framework import serializers, status from rest_framework.authtoken.models import Token from rest_framework.authtoken.views import ObtainAuthToken from rest_framework.response import Response from rest_framework.views import APIView from django.contrib.auth.hashers import make_password +from django.utils import timezone from rest_framework.permissions import IsAuthenticated from django_filters import rest_framework as filters from system.tasks import update_user_login_info -from system.models import User, Menu, Dept +from system.models import User, Menu, Dept, LoginLog from utils.ip_utils import get_client_ip +from utils.models import CommonStatus from utils.serializers import CustomModelSerializer from utils.custom_model_viewSet import CustomModelViewSet @@ -52,29 +54,59 @@ class UserLogin(ObtainAuthToken): def post(self, request, *args, **kwargs): serializer = self.serializer_class(data=request.data, context={'request': request}) - serializer.is_valid(raise_exception=True) - user = serializer.validated_data['user'] - token, created = Token.objects.get_or_create(user=user) - - # 获取真实IP地址 client_ip = get_client_ip(request) + username = request.data.get('username', '') + try: + serializer.is_valid(raise_exception=True) + user = serializer.validated_data['user'] + if user.status == CommonStatus.DISABLED: + update_user_login_info.delay( + username, + client_ip, + request.META.get('HTTP_USER_AGENT', ''), + LoginLog.LoginResult.FAILED + ) + return Response({ + "code": 1, + "data": None, + "message": "登录失败, 用户被禁用" + }) + token, created = Token.objects.get_or_create(user=user) + user.login_ip = client_ip + user.last_login = timezone.now() + user.save(update_fields=['login_ip', 'last_login']) + # 异步处理用户登录信息更新和日志记录 + update_user_login_info.delay( + username, + client_ip, + request.META.get('HTTP_USER_AGENT', ''), + LoginLog.LoginResult.SUCCESS + ) - # 异步处理用户登录信息更新和日志记录 - update_user_login_info.delay( - user.id, - client_ip, - request.META.get('HTTP_USER_AGENT', '') - ) + user_data = UserSerializer(user).data + # 在序列化后的数据中加入 accessToken + user_data['accessToken'] = token.key + return Response({ + "code": 0, + "data": user_data, + "error": None, + "message": "ok" + }) - user_data = UserSerializer(user).data - # 在序列化后的数据中加入 accessToken - user_data['accessToken'] = token.key - return Response({ - "code": 0, - "data": user_data, - "error": None, - "message": "ok" - }) + except Exception as e: + # 记录登录失败日志 + update_user_login_info.delay( + username, + client_ip, + request.META.get('HTTP_USER_AGENT', ''), + LoginLog.LoginResult.FAILED + ) + + return Response({ + "code": 1, + "data": None, + "message": "登录失败, 用户名或密码错误" + }) def get_location_from_ip(self, ip): """根据IP地址获取地理位置信息"""