feat:添加获取it地址
This commit is contained in:
@@ -16,7 +16,7 @@ COPY . .
|
||||
RUN pip install -r requirements.txt -i https://mirrors.aliyun.com/pypi/simple
|
||||
# 入口命令由 docker-compose 控制
|
||||
# 数据库迁移
|
||||
#RUN python manage.py makemigrations && python manage.py migrate
|
||||
RUN python manage.py migrate
|
||||
# 收集静态文件
|
||||
RUN python manage.py collectstatic --noinput
|
||||
|
||||
|
||||
@@ -14,4 +14,5 @@ goofish_api==0.0.6
|
||||
flower==2.0.1
|
||||
gunicorn==23.0.0
|
||||
django_redis==6.0.0
|
||||
django-ninja==1.4.3
|
||||
django-ninja==1.4.3
|
||||
ip2geotools==0.1.6
|
||||
20
backend/system/migrations/0003_loginlog_location.py
Normal file
20
backend/system/migrations/0003_loginlog_location.py
Normal file
@@ -0,0 +1,20 @@
|
||||
# Generated by Django 5.2.1 on 2025-08-13 03:28
|
||||
|
||||
from django.db import migrations, models
|
||||
|
||||
|
||||
class Migration(migrations.Migration):
|
||||
|
||||
dependencies = [
|
||||
("system", "0002_alter_dept_creator_alter_dept_is_deleted_and_more"),
|
||||
]
|
||||
|
||||
operations = [
|
||||
migrations.AddField(
|
||||
model_name="loginlog",
|
||||
name="location",
|
||||
field=models.CharField(
|
||||
blank=True, db_comment="<IP> 地理位置", default="", max_length=200
|
||||
),
|
||||
),
|
||||
]
|
||||
@@ -296,6 +296,7 @@ class LoginLog(CoreModel):
|
||||
result = models.IntegerField(choices=LoginResult.choices, default=LoginResult.SUCCESS, db_comment='登录结果')
|
||||
user_ip = models.CharField(max_length=50, db_comment='用户 IP')
|
||||
user_agent = models.CharField(max_length=512, db_comment='浏览器 UA')
|
||||
location = models.CharField(max_length=200, db_comment='<IP> 地理位置', blank=True, default='')
|
||||
|
||||
class Meta:
|
||||
db_table = 'system_login_log'
|
||||
|
||||
@@ -8,6 +8,7 @@ from rest_framework.views import APIView
|
||||
from django.contrib.auth.hashers import make_password
|
||||
from rest_framework.permissions import IsAuthenticated
|
||||
from django_filters import rest_framework as filters
|
||||
from ip2geotools.databases.noncommercial import DbIpCity
|
||||
|
||||
from system.models import User, Menu, LoginLog, Dept
|
||||
from utils.ip_utils import get_client_ip
|
||||
@@ -59,7 +60,10 @@ class UserLogin(ObtainAuthToken):
|
||||
|
||||
# 获取真实IP地址
|
||||
client_ip = get_client_ip(request)
|
||||
|
||||
|
||||
# 获取IP地址的地理位置信息
|
||||
location_info = self.get_location_from_ip(client_ip)
|
||||
|
||||
# 更新登录IP和登录时间
|
||||
user.login_ip = client_ip
|
||||
user.last_login = timezone.now()
|
||||
@@ -70,6 +74,7 @@ class UserLogin(ObtainAuthToken):
|
||||
username=user.username,
|
||||
result=LoginLog.LoginResult.SUCCESS,
|
||||
user_ip=client_ip,
|
||||
location=location_info,
|
||||
user_agent=request.META.get('HTTP_USER_AGENT', '')
|
||||
)
|
||||
# 在序列化后的数据中加入 accessToken
|
||||
@@ -81,6 +86,33 @@ class UserLogin(ObtainAuthToken):
|
||||
"message": "ok"
|
||||
})
|
||||
|
||||
def get_location_from_ip(self, ip_address):
|
||||
"""根据IP地址获取地理位置信息"""
|
||||
try:
|
||||
# 对于本地IP地址,返回默认值
|
||||
if ip_address in ['127.0.0.1', 'localhost']:
|
||||
return "本地网络"
|
||||
|
||||
# 查询IP地址信息
|
||||
response = DbIpCity.get(ip_address, api_key='free')
|
||||
|
||||
# 构建地区信息字符串
|
||||
location_parts = []
|
||||
if response.city:
|
||||
location_parts.append(response.city)
|
||||
if response.region:
|
||||
location_parts.append(response.region)
|
||||
if response.country:
|
||||
location_parts.append(response.country)
|
||||
|
||||
return ', '.join(location_parts) if location_parts else "未知位置"
|
||||
|
||||
except Exception as e:
|
||||
# 记录错误日志
|
||||
import logging
|
||||
logger = logging.getLogger(__name__)
|
||||
logger.error(f"获取IP地址位置信息失败: {str(e)}")
|
||||
return "位置获取失败"
|
||||
|
||||
class UserInfo(APIView):
|
||||
|
||||
|
||||
@@ -79,7 +79,12 @@ export function useColumns(): VxeTableGridOptions<SystemLoginLogApi.SystemLoginL
|
||||
},
|
||||
{
|
||||
field: 'user_ip',
|
||||
title: '登录地址',
|
||||
title: '登录ip',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
field: 'location',
|
||||
title: '登录地区',
|
||||
width: 150,
|
||||
},
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user