php - nginx 可以处理重复的 X-Forwarded-For header 吗?

标签 php nginx

当用户使用代理(Google 数据保护程序等)时,浏览器会为客户端的真实 IP 地址添加 X-Forwarded-For 到服务器。我们的负载均衡器将所有 header +客户端的 IP 地址作为 X-Forwarded-For header 传递给 nginx 服务器。示例请求 header :

X-Forwarded-For: 1.2.3.4
X-Forwarded-Port: 80
X-Forwarded-Proto: http
Host: *.*.*.*
Accept-Encoding: gzip, deflate, sdch
Accept-Language: en-US,en;q=0.8,tr;q=0.6
Save-Data: on
Scheme: http
Via: 1.1 Chrome-Compression-Proxy
X-Forwarded-For: 1.2.3.5
Connection: Keep-alive

有没有办法将两个 X-Forwarded-For header 分别传递给 php?

最佳答案

长话短说

  • nginx:fastcgi_param HTTP_MERGED_X_FORWARDED_FOR $http_x_forwarded_for
  • php: $_SERVER['HTTP_MERGED_X_FORWARDED_FOR']

解释

您可以使用 the $http_<header_name> variable 访问所有 http header .当使用这个变量时,nginx 甚至会为你做头合并

CustomHeader: foo
CustomHeader: bar

转换为值:

foo, bar

因此,您需要做的就是将此变量传递给 php with fastcgi_param

fastcgi_param HTTP_MERGED_X_FORWARDED_FOR $http_x_forwarded_for

概念验证:

在您的 nginx 服务器 block 中:

location ~ \.php$ {
    fastcgi_pass unix:run/php/php5.6-fpm.sock;
    fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
    fastcgi_param HTTP_MERGED_X_FORWARDED_FOR $http_x_forwarded_for;
    include fastcgi_params;
}

test.php

<?php
die($_SERVER['HTTP_MERGED_X_FORWARDED_FOR']);

最后看看 curl 会发生什么:

curl -v -H 'X-Forwarded-For: 127.0.0.1' -H 'X-Forwarded-For: 8.8.8.8' http://localhost/test.php

给出以下响应:

* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 80 (#0)
> GET /test.php HTTP/1.1
> Host: localhost
> User-Agent: curl/7.47.0
> X-Forwarded-For: 127.0.0.1
> X-Forwarded-For: 8.8.8.8
> 
< HTTP/1.1 200 OK
< Server: nginx/1.10.3 (Ubuntu)
< Date: Wed, 01 Nov 2017 09:07:51 GMT
< Content-Type: text/html; charset=UTF-8
< Transfer-Encoding: chunked
< Connection: keep-alive
< 
* Connection #0 to host localhost left intact
127.0.0.1, 8.8.8.8

轰!好了,您可以访问所有 X-FORWARDED-FOR header ,作为 $_SERVER['HTTP_MERGED_X_FORWARDED_FOR'] 中的逗号分隔字符串

当然,您可以使用任何您想要的名称,而不仅仅是 HTTP_MERGED_X_FORWARDED_FOR .

关于php - nginx 可以处理重复的 X-Forwarded-For header 吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39078447/

相关文章:

php - JSON 解析对象为 javascript 函数 : syntaxerror

php - 注销后浏览器后退按钮

nginx - nginx 只接受子域名

ssl - 生成没有配置文件的 OpenSSL CRL 文件

php - 如何使用 php system() 函数正确运行 mysql 命令?

php - 通过 jQuery Ajax 将西里尔文本作为 JSON 从 localStorage 传递到 MySQL

php - 如何在将 .CSV 格式的文件导入 SQL 时验证员工 ID?

同时在fedora上运行php7和php5

nginx - 禁用 404 错误日志记录

php - nginx 将一些 PHP URL 作为下载而不是执行