Comment obtenir l'adresse IP réelle du client à travers un proxy nginx/apache ?
En utilisant nginx/apache comme proxy pour workerman, nginx/apache agit en réalité en tant que client de workerman. Par conséquent, l'adresse IP du client obtenue sur workerman est l'adresse IP du serveur nginx/apache, et non l'adresse IP réelle du client. Vous pouvez vous référer aux méthodes ci-dessous pour obtenir l'adresse IP réelle du client.
Principe :
nginx/apache transmet l'adresse IP réelle du client via un en-tête HTTP, par exemple en ajoutant dans la configuration de nginx sous location proxy_set_header X-Real-IP $remote_addr; . Workerman lit cette valeur d'en-tête, la sauvegarde dans le $connection object (GatewayWorker peut la sauvegarder dans la variable $_SESSION), et vous pouvez y accéder directement en lisant la variable.
Remarque :
Les configurations suivantes s'appliquent aux protocoles http/https ws/wss. Pour d'autres protocoles, la méthode pour obtenir l'adresse IP du client est similaire, nécessitant que le serveur proxy insère des données d'IP dans le paquet pour transmettre l'adresse IP réelle du client.
Configuration de nginx ressemble à ceci :
server {
listen 443;
ssl on;
ssl_certificate /etc/ssl/server.pem;
ssl_certificate_key /etc/ssl/server.key;
ssl_session_timeout 5m;
ssl_session_cache shared:SSL:50m;
ssl_protocols SSLv3 SSLv2 TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ALL:!ADH:!EXPORT56:RC4+RSA:+HIGH:+MEDIUM:+LOW:+SSLv2:+EXP;
location /wss
{
proxy_pass http://127.0.0.1:8282;
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
# Cette partie utilise l'en-tête http pour transmettre l'adresse IP réelle du client
proxy_set_header X-Real-IP $remote_addr;
}
# location / {} Autres configurations du site...
}
Workerman lit l'adresse IP du client à partir de l'en-tête configuré par nginx
<?php
use Workerman\Worker;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';
$worker = new Worker('websocket://0.0.0.0:7272');
/**
* Callback onWebSocketConnect lors de la connexion websocket du client
* Obtenir la valeur X_REAL_IP transmise par nginx dans l'en-tête http
*/
$worker->onWebSocketConnect = function(TcpConnection $connection, $request){
/**
* L'objet connection n'a pas d'attribut realIP, ici nous ajoutons dynamiquement un attribut realIP à l'objet connection
* N'oubliez pas que les objets PHP peuvent avoir des attributs ajoutés dynamiquement, vous pouvez aussi utiliser le nom d'attribut que vous préférez
*/
//$connection->realIP = $_SERVER['HTTP_X_REAL_IP']; // Utilisation pour workerman v4
$connection->realIP = $request->header('x-real-ip'); // Utilisation pour workerman v5
};
$worker->onMessage = function(TcpConnection $connection, $data)
{
// Lors de l'utilisation de l'adresse IP réelle du client, utilisez directement $connection->realIP
$connection->send($connection->realIP);
};
Worker::runAll();
GatewayWorker obtient l'adresse IP du client à partir de l'en-tête configuré par nginx
Ajoutez le code suivant dans Events.php
class Events
{
public static function onWebsocketConnect($client_id, $data)
{
$_SESSION['realIP'] = $data['server']['HTTP_X_REAL_IP'];
}
// .... Autres codes omis ....
}
Après avoir ajouté le code, vous devez redémarrer GatewayWorker.
Ainsi, vous pourrez accéder à l'adresse IP réelle du client à l'aide de $_SESSION['realIP'] dans les méthodes onMessage et onClose de Events.php.
Remarque : Dans Events.php,
onWorkerStart,onConnect, etonWorkerStopne peuvent pas utiliser directement$_SESSION['realIP'].