You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python/Django中如何正确获取当前登录用户的真实IP地址

问题根源

你最初使用的socket库相关方法,作用是读取运行代码的服务器自身的主机名和绑定IP,本地开发时你的电脑同时承担客户端、服务端角色,所以返回结果看起来符合预期;项目部署到线上服务器后,服务端和访问用户的客户端分属不同设备,该方法自然只能返回线上服务器自身的信息,不可能拿到访问用户的端侧数据。

正确实现思路

用户的访问IP是通过HTTP请求携带的,你需要从Web框架接收到的请求对象中提取对应字段,不要用服务器本地socket方法查询。另外要注意:公网场景下几乎无法准确获取用户端本地设置的主机名——HTTP协议不会主动透传用户设备的本地主机名,对用户IP做反向解析的结果绝大多数是运营商网关域名,和用户实际主机名无关,建议不要把用户主机名作为核心业务依赖字段。

不同Web框架的代码实现

首先要注意:如果你的服务前面挂了Nginx、CDN、云负载均衡等反向代理层,需要先在代理层配置规则,把用户真实IP透传到后端服务,否则后端拿到的永远是代理节点的IP。

  • Flask 框架示例
import socket
from flask import request

@app.route('/login', methods=['POST'])
def login():
    # 优先取反代透传的真实IP,无反代时取直连IP
    if request.headers.get('X-Forwarded-For'):
        # X-Forwarded-For 格式为 [用户真实IP, 一级代理IP, 二级代理IP...],取第一个非空值即可
        user_ip = request.headers.get('X-Forwarded-For').split(',')[0].strip()
    else:
        user_ip = request.remote_addr
    
    # 尝试反向解析主机名,必须加异常兜底,大部分场景会解析失败
    try:
        user_hostname = socket.gethostbyaddr(user_ip)[0]
    except:
        user_hostname = "未知"
    
    # 后续登录业务逻辑
  • Django 框架示例
import socket

def login(request):
    if request.META.get('HTTP_X_FORWARDED_FOR'):
        user_ip = request.META.get('HTTP_X_FORWARDED_FOR').split(',')[0].strip()
    else:
        user_ip = request.META.get('REMOTE_ADDR')
    
    # 主机名解析逻辑同上,做好失败兜底
    try:
        user_hostname = socket.gethostbyaddr(user_ip)[0]
    except:
        user_hostname = "未知"
    
    # 后续登录业务逻辑

反向代理配置参考(Nginx)

如果用Nginx做反向代理,需要在配置中增加透传规则,否则后端无法拿到真实用户IP:

location / {
    proxy_pass http://你的后端服务监听地址;
    proxy_set_header X-Forwarded-For $remote_addr;
}
关键注意事项
  • 不要信任前端主动传入的IP参数,所有IP字段必须从服务端接收到的原始请求头中提取,避免用户伪造IP绕过业务校验
  • 多层代理场景下,需要确认最外层代理已经正确把用户真实IP写入X-Forwarded-For字段的第一位,避免取到中间代理的IP
  • 用户主机名字段解析成功率极低,仅作辅助信息使用,不要作为登录校验、风控判断的核心依据

内容的提问来源于stack exchange,提问作者Ibrahim Khan

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 22:09:18