PHP实战开发23-PHP结合Nginx获取用户真实IP地址

news2024/12/25 9:48:56

文章目录

  • 一、前言
  • 二、关于用户IP的背景知识
    • 2.1 HTTP请求
    • 2.2 HTTP代理服务器
    • 2.3 X-Forwarded-For头部
  • 三、代码实现
    • 3.1 Nginx配置
    • 3.2 PHP代码处理
  • 总结


一、前言

本文已收录于PHP全栈系列专栏:PHP快速入门与实战

在Web应用程序中,IP地址是常见的数据项。例如,它可以用于用户认证、访问控制、日志记录和其他安全功能。然而,在某些情况下,获取客户端的真实IP地址可能会变得非常困难。
在这里插入图片描述

由于HTTP协议的本质,当您从Web服务器接收请求时,它只包含HTTP头中的客户端的最后一个代理服务器的IP地址。这称为X-Forwarded-For头。

因此,如果您希望了解客户端的真实IP地址,则需要深入探究HTTP请求如何跨多个代理服务器传递。

本文将向您展示如何使用PHP和Nginx来获取客户端的真实IP地址。

二、关于用户IP的背景知识

在深入探讨代码之前,我们需要先了解一些基础知识。如什么是HTTP,HTTP请求包含了哪些信息。请求到服务器这个过程是怎么一回事等。

2.1 HTTP请求

在这里插入图片描述

HTTP请求由请求行、请求头和请求体组成。

请求行指定请求方法(GET、POST等)、URI和HTTP协议的版本号。

请求头包含HTTP版本、Host头、User-Agent头、Cookie头和其他自定义头部。

请求体包含客户端提交的数据,通常是表单数据或JSON数据。

2.2 HTTP代理服务器

HTTP代理服务器是介于客户端和Web服务器之间的一种服务器。代理服务器可以用于缓存、负载均衡、安全性和其他目的。当客户端向代理服务器发出HTTP请求时,代理服务器将该请求转发到下一个目标服务器。

在这里插入图片描述

2.3 X-Forwarded-For头部

X-Forwarded-For头是一种HTTP头部,用于指示客户端的真实IP地址。当Web服务器从代理服务器接收请求时,它会检查X-Forwarded-For头,并提取最后一个IP地址。如果此头不存在,则Web服务器将使用代理服务器的IP地址。

如果请求通过多个代理服务器传递,则每个代理服务器都可以在X-Forwarded-For头中添加一个IP地址。在这种情况下,最后一个IP地址是客户端的真实IP地址。

三、代码实现

3.1 Nginx配置

PHP代码正常工作,我们需要在Nginx服务器上启用X-Forwarded-For头部。这是通过将以下行添加到Nginx配置文件中完成的:

proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

此行告诉Nginx将客户端的IP地址添加到X-Forwarded-For头中。当请求被转发时,代理服务器将检查此头以提取客户端的真实IP地址。

以下是完整的Nginx配置文件示例:

server {
    listen 80;
    server_name example.com;
 
    access_log /var/log/nginx/example.access.log main;
    error_log /var/log/nginx/example.error.log;
 
    location / {
        proxy_pass http://127.0.0.1:9000;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    }
}

此配置将所有请求转发到本地主机上运行的HTTP服务器。每个传入请求都会添加一个X-Forwarded-For头并转发到9000端口。

3.2 PHP代码处理

以下是获取客户端真实IP地址的PHP代码:

function get_ip_address() {
    // Check for shared Internet/ISP IP
    if (!empty($_SERVER['HTTP_CLIENT_IP']) && validate_ip($_SERVER['HTTP_CLIENT_IP'])) {
        return $_SERVER['HTTP_CLIENT_IP'];
    }
 
    // Check for IP passed in via HTTP_X_FORWARDED_FOR header
    if (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        // Check if multiple IP addresses exist in this header
        $ip_addresses = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
 
        foreach ($ip_addresses as $ip) {
            if (validate_ip($ip)) {
                return $ip;
            }
        }
    }
 
    // Check for IP passed in via REMOTE_ADDR header
    if (validate_ip($_SERVER['REMOTE_ADDR'])) {
        return $_SERVER['REMOTE_ADDR'];
    }
 
    // Return unreliable IP address since all else failed
    return $_SERVER['REMOTE_ADDR'];
}
 
function validate_ip($ip) {
    if (strtolower($ip) === 'unknown') {
        return false;
    }
 
    // Generate IPv4 network address
    $ipv4_network = ip2long('0.0.0.0/24');
 
    // Generate IPv6 network address
    $ipv6_network = inet_pton('::ffff:0.0.0.0') . '/96';
 
    // Check if IP address is IPv4
    if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) !== false) {
        // Convert IP to IPv4 network address
        $ip_network = ip2long($ip) & ~((1 << (32 - 24)) - 1);
 
        return $ip_network === $ipv4_network;
    }
 
    // Check if IP address is IPv6
    if (filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) !== false) {
        // Convert IP to IPv6 network address
        $ip_network = inet_pton($ip) & ~((1 << (128 - 96)) - 1);
 
        return $ip_network === $ipv6_network;
    }
 
    return false;
}

此代码使用3种方法来检测客户端的真实IP地址:

  1. 如果HTTP_CLIENT_IP头部存在且有效,则返回该IP地址。

  2. 如果HTTP_X_FORWARDED_FOR头部存在,则迭代其值,并返回第一个有效IP地址。

  3. 如果REMOTE_ADDR头部存在且有效,则返回该IP地址。

  4. 如果所有检查都失败,则返回REMOTE_ADDR头中的IP地址。

validate_ip()函数用于检查传递的IP地址是否有效。以下是它的工作原理:

  1. 检查地址是否为“unknown”。

  2. 生成IPv4和IPv6的网络地址。

  3. 检测IP地址是否为IPv4,并将其转换为网络地址。如果地址匹配IPv4网络地址,则返回true。

  4. 检测IP地址是否为IPv6,并将其转换为网络地址。如果地址匹配IPv6网络地址,则返回true。

总结

以上内容介绍了如何通过PHP结合Nginx实现获取用户真实IP地址。我们从了解了HTTP请求和代理服务器的工作原理出发,并讨论了X-Forwarded-For头的作用。最后演示了如何编写有效的PHP代码来获取客户端真实IP地址。
在这里插入图片描述
相信通过本文,你对获取用户真实IP地址有了更深入的理解,如果你有什么疑问或者建议,欢迎在下方评论区留言。后续更多内容将收录在专栏PHP快速入门与实战中,感谢大家支持。喜欢记得三联哟。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/668800.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Flink 学习四 Flink 基础架构

Flink 学习四 Flink 基础架构&算子链&槽位 文章大部分数据来源 : https://nightlies.apache.org/flink/flink-docs-release-1.14/docs/concepts/flink-architecture/ Flink 是一个分布式系统,需要有效的分配和管理计算资源才可以执行流式程序; 集成了常见的资源管理…

chatgpt赋能python:Python简介

Python简介 Python是一种高级编程语言&#xff0c;具有易读性和简洁性的特点。它被广泛使用于Web开发、数据科学、人工智能、机器学习和自动化测试等领域。Python也是一种非常适合新手学习编程的语言。 在本篇文章中&#xff0c;我们将讨论如何使用Python提取指定内容以进行S…

【BMS】电池包硬件方案选型指南

🔋电池包硬件方案选型指南🔋 BMS硬件系统需求主要包括:测温模块、测流模块、测压模块、系统电源、保护电路、故障检测电路,本文阐述各个功能模块在不同场景下的电池包硬件系统方案选择。 一、测温 NTC(热敏电阻) 电池包测温一般包括表皮温度、内部温度、PCB温度(极片布…

[自定义组件]微信小程序自定义组件实现缩略图和原图分离及可缩放效果

目录 目标及基础环境背景 实现原理左右滑动缩放图片菜单 开发实现自定义组件wxml组件结构wxss 样式控制js定义属性及回调json声明为组件 使用添加组件声明及地址声明为全局组件(也可声明为局部)声明为全局组件&#xff08;也可以声明为全局组件&#xff09;使用组件 效果展示 附…

pycharm安装, 汉化 , 使用教程

目录 1.下载安装包 2.汉化 3.使用 1.下载安装包 访问Pycharm官网 根据自己的操作系统下载对应版本的Pycharm Community或Professional Edition。 2.汉化 点击“file”选项&#xff0c;然后点击“setting”&#xff0c;再点击“plugins”选项&#xff1b; 输入“Chinese”找…

使用Frp进行反向代理实现远程桌面控制[teamviewer/nomachine]

.使用Frp进行反向代理实现远程桌面控制 V1.0.0 – by Holden Date : 2023-06-20 文章目录 .使用Frp进行反向代理实现远程桌面控制1. 简介2. 工具准备3. 服务器端搭建4. 受控端配置&&运行teamviewer5. 控制机端运行teamviewer6. 切换成nomachine 1. 简介 ​ frp 是一…

winform多语言资源管理

SailingEase WinForm Framework WinForm开发框架开发手册&#xff1a;http://docs.shengxunwei.com/Home/Browser/sewinformfw/ 这是我2010年左右&#xff0c;写 Winform IDE &#xff08;使用 .NET WinForm 开发所见即所得的 IDE 开发环境&#xff0c;实现不写代码直接生成应用…

什么是算法

有人说程序算法数据结构&#xff0c;虽说这样的认为有失偏颇&#xff0c;一个程序决定的东西实在太多&#xff0c;但某些方面也说明了算法是很重要的&#xff08;数据结构承上启下&#xff0c;最终也是要为算法服务&#xff09;。 算法是用来解决问题的&#xff0c;要理解什么是…

AI Image Codec技术落地实践

AI Codec自2016年首次提出以来&#xff0c;众多海内外高校、企业研究院等机构对此展开了广泛研究。6年时间里&#xff0c;AI Codec 的SOTA方案的压缩性能已经超越了H.266(最新的传统Codec标准)&#xff0c;展现了强大的技术潜力。但受限于计算复杂度、非标等原因&#xff0c;AI…

Vue中的JSX的特性

JSX简介 JSX是一种Javascript的语法扩展&#xff0c;即具备了Javascript的全部功能&#xff0c;同时又兼具html的语义化和直观性。它可以让我们在JS中写模板语法&#xff1a; const el <div>Vue 2</div>; 复制代码上面这段代码既不是 HTML 也不是字符串&#xf…

java阿里云sls基于LoghubAppender自定义日志上传

1、背景&#xff1a;阿里sls日志提供快捷日志平台&#xff0c;平替elk公司使用这个日志服务&#xff0c;需要对接写入日志 目前日志集成有3种 1&#xff09;基于封装manager手动写日志手动send 弊端&#xff1a;本地日志和阿里云日志共用日志代码很臃肿 2&#xff09;基于云服…

开启数字时代,分享电脑监控和录制工具

近年来&#xff0c;随着网络技术的快速发展和普及&#xff0c;电脑屏幕录制和监控越来越成为企业、学校、家庭等不可或缺的工具。无论是在线教学、远程工作&#xff0c;还是家长对孩子上网行为的关注&#xff0c;电脑屏幕录制和监控都具有极大的帮助和重要性。今天就给大家推荐…

【Visual Studio】使用 C++ 语言,配合 Qt,开发了一个串口通信界面

知识不是单独的&#xff0c;一定是成体系的。更多我的个人总结和相关经验可查阅这个专栏&#xff1a;Visual Studio。 文章目录 1. 获取串口名字1.1 文件 GUI.ui1.2 文件 GUI.h1.3 文件 GUI.cpp 2. 配置串口连接2.1 文件 GUI.ui2.2 文件 GUI.h2.3 文件 GUI.cpp 3. 配置串口连接…

chatgpt赋能python:Python排错大全:10年经验总结,快速定位并解决问题!

Python排错大全&#xff1a;10年经验总结&#xff0c;快速定位并解决问题&#xff01; 作为一名有着10年Python编程经验的工程师&#xff0c;在这篇文章中&#xff0c;我将详细介绍常见的Python排错技巧&#xff0c;以及我在实际工作中使用的一些技巧和最佳实践。我们将学习如…

《网络安全0-100》安全策略制定

安全策略制定 安全策略制定是指制定一系列的规范、标准和 流程&#xff0c;以保护企业或组织的信息资源和业务活 动&#xff0c;确保其安全性和可靠性。安全策略制定通 常包括以下几个步骤&#xff1a; 风险评估&#xff1a;对企业或组织的信息系统进行全面 评估&#xff…

Electron 和 Angular 项目升级

Electron 和 Angular 项目升级: Angular4Electron1.7.8 升级到 Angular13Electron2 原项目 Angular 和 Electron 版本: angular/cli: 1.4.9angular/core: 4.4.6Electron: 1.7.8 升级后 Angular 和 Electron 版本: Angular: 13.3.1Electron: 21.2.1 流程: angular-electro…

一次服务器被入侵的处理过程分享

一、服务器入侵现象 近期有一个朋友的服务器(自己做了网站)好像遭遇了入侵&#xff0c;具体现象是&#xff1a; 服务器 CPU 资源长期 100%&#xff0c;负载较高。 服务器上面的服务不能正常提供服务。 ​ 朋友处理了一会没有解决&#xff0c;我开始想说我不是搞安全的&#xf…

【Visual Studio】报错 LNK2019,使用 C++ 语言,配合 Qt 开发串口通信界面

知识不是单独的&#xff0c;一定是成体系的。更多我的个人总结和相关经验可查阅这个专栏&#xff1a;Visual Studio。 文章目录 问题解决方案Ref. 问题 使用 C 语言&#xff0c;配合 Qt 开发串口通信界面时&#xff0c;报错代码 LNK2019。 复制以下错误信息&#xff0c;方便别…

15、SQL注入之Oracel,MongoDB等注入

这里写目录标题 引言补充上篇文章Json注入案例分析 简要学习各种数据库的注入特点Access数据库Mssql数据库PostgreSQL数据库Oracle数据库MongoDB数据库 简要学习各种注入工具的使用指南 引言 mysql的注入方法跟其它的数据库注入方法是差不多的&#xff0c;是可以举一反三的&am…

【Pandas】pandas用法解析(下)

一、生成数据表 二、数据表信息查看 三、数据表清洗 四、数据预处理 ———————————————— 目录 五、数据提取 1.按索引提取单行的数值 2.按索引提取区域行数值 3.重设索引 4.设置日期为索引 5.提取4日之前的所有数据 6.使用iloc按位置区域提取数据 7…