【问题标题】:Getting a user's IP address in Laravel through Docker containers and Nginx webserver通过 Docker 容器和 Nginx 网络服务器在 Laravel 中获取用户的 IP 地址
【发布时间】:2021-05-28 05:01:51
【问题描述】:

早安,

我的问题是,当我使用 Laravel 的 $request->ip() 或 $request->getClientIp () 或 $request->server->get('REMOTE_ADDR') 或 $_SERVER['REMOTE_ADDR'] 时,我只获取我的 Docker 网络 IP 地址,这基本上都是我假设的。 到目前为止,问题出现在我的本地测试电脑(没有 Nginx 反向代理)以及我的实时服务器上

我希望我在下面提供了足够的相关信息,如果没有,请告诉我:) 提前致谢!

所以我的设置如下(简化),两个 Nginx 配置也粘贴在下面:

Server -> Nginx Reverse Proxy -> Docker Containers & Network (db, php, nginx, redis) -> Nginx Webserver <-> PHP-FPM

与_SERVER相关的一些结果:

[SERVER_ADDR] => 172.20.0.3 (nginx webserver)
[REMOTE_PORT] => 55378
[REMOTE_ADDR] => 172.20.0.1 (docker network / gateway)
[SERVER_SOFTWARE] => nginx/1.19.6

在尝试和更改配置等时,我已经阅读了数小时和数小时的多个论坛和解决方案,但似乎都没有工作。

我尝试过的:

所以我也尝试在 Laravel 的 /Http/Middleware/TrustProxies.php 中设置我的“可信代理”,方法是允许所有:protected $proxies = '*';

我也不需要这些额外的 Laravel 包 >5.5 我相信这是 Laravel (TrustProxies) 的内置功能。

请在下面找到我的 Nginx 网络服务器配置:

server {
    listen 80;
    server_name domain.com;
    return 301 https://www.example.com;
}

server {
    listen 80 default_server;

    index index.html index.htm index.php;

    server_name www.example.com;

    root /var/www/public;

    location ~ \.php$ {
        try_files $uri =404;
        fastcgi_split_path_info ^(.+\.php)(/.+)$;
        fastcgi_pass php-fpm:9013;
        fastcgi_index index.php;
        include fastcgi_params;
        fastcgi_param SCRIPT_FILENAME /var/www/example.com/public/$fastcgi_script_name;
        fastcgi_param PATH_INFO $fastcgi_path_info;
    }
    
   # Support Clean (aka Search Engine Friendly) URLs & enable Gzip compression:
    location / {
        proxy_set_header    X-Real-IP            $remote_addr;
        proxy_set_header    X-Forwarded-For      $proxy_add_x_forwarded_for;
        try_files $uri $uri/ /index.php?$query_string;
        gzip_static on;
    }
   # Override the load balancer IP with real IP.
    fastcgi_param REMOTE_ADDR $http_x_real_ip;

    error_log  /var/log/nginx/error.log;
    access_log /var/log/nginx/access.log;
}

还有我服务器的 Nginx 反向代理配置(如果相关):

server {
    listen 80;
    listen [::]:80;

    server_name     example.com.au www.example.com.au;

    location / {
        proxy_pass      http://localhost:8013;
        proxy_set_header   Host $host;
        proxy_set_header   X-Real-IP $remote_addr;
        proxy_set_header   X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header   X-Forwarded-Host $server_name;
    }
}

【问题讨论】:

  • 我刚刚意识到,也许在我的本地 pc/localhost 上也作为服务器运行,这可能是预期的行为??
  • 如果在本地主机上这是预期的行为,我仍然很想知道如何在我的实时服务器上实现这一点,如问题中所述

标签: php docker nginx nginx-reverse-proxy laravel-8


【解决方案1】:

好的,想通了! :D

  1. 我使用 Cloudflare 作为代理,我的 DNS 使用 CloudFlare,由于速度/缓存改进,我启用了“通过 CloudFlare 代理”选项。 这导致 CloudFlare 将HTTP_CF_CONNECTING_IP“注入”到我的标题中。 为了检索这个标头值,我在代码中使用了$_SERVER['HTTP_CF_CONNECTING_IP']。

  2. 另一种解决方案是通过使用_SERVER['HTTP_X_FORWARDED_FOR'] 来使用标题中的HTTP_X_FORWARDED_FOR 值,我相信这在我的情况下只有在执行以下操作后才有效(发布在我的问题中):

  • TrustProxies.php
  • proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;

我希望这对其他人也有帮助:D

【讨论】:

  • Laravel 不应该通过$this-&gt;ip() 提供这个开箱即用的功能吗?它使用底层的getClientIp() 函数,描述状态为This method can read the client IP address from the "X-Forwarded-For" header * when trusted proxies were set via "setTrustedProxies()"...。
  • 嗨@superfly 是的,我相信这是正确的。这就是我开始的方式,但我没有让它工作,它一直带着我的代理 IP 返回。也许我的问题是同时使用 Cloudflare?所以是的,我只是选择了要使用的 CF 标头值,但实际上,理论上你应该能够在 Laravel 配置中设置trustedProxies,瞧……
猜你喜欢
  • 2020-09-01
  • 2021-01-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多