diff --git a/sanic/request/types.py b/sanic/request/types.py index 98f6e908..53d1a402 100644 --- a/sanic/request/types.py +++ b/sanic/request/types.py @@ -838,19 +838,31 @@ class Request(Generic[sanic_type, ctx_type]): @property def remote_addr(self) -> str: """ - Client IP address, if available. - 1. proxied remote address `self.forwarded['for']` - 2. local remote address `self.ip` + Client IP address, if available from proxy. :return: IPv4, bracketed IPv6, UNIX socket name or arbitrary string :rtype: str """ if not hasattr(self, "_remote_addr"): - self._remote_addr = str( - self.forwarded.get("for", "") - ) # or self.ip + self._remote_addr = str(self.forwarded.get("for", "")) return self._remote_addr + @property + def client_ip(self) -> str: + """ + Client IP address. + 1. proxied remote address `self.forwarded['for']` + 2. local peer address `self.ip` + + New in Sanic 23.6. Prefer this over `remote_addr` for determining the + client address regardless of whether the service runs behind a proxy + or not (proxy deployment needs separate configuration). + + :return: IPv4, bracketed IPv6, UNIX socket name or arbitrary string + :rtype: str + """ + return self.remote_addr or self.ip + @property def scheme(self) -> str: """ diff --git a/tests/test_requests.py b/tests/test_requests.py index 4a995d4c..6719025b 100644 --- a/tests/test_requests.py +++ b/tests/test_requests.py @@ -513,6 +513,7 @@ def test_standard_forwarded(app): request, response = app.test_client.get("/", headers=headers) assert response.json == {"for": "127.0.0.2", "proto": "ws"} assert request.remote_addr == "127.0.0.2" + assert request.client_ip == "127.0.0.2" assert request.scheme == "ws" assert request.server_name == "local.site" assert request.server_port == 80 @@ -737,6 +738,7 @@ def test_remote_addr_with_two_proxies(app): headers = {"X-Forwarded-For": "127.0.1.1"} request, response = app.test_client.get("/", headers=headers) assert request.remote_addr == "" + assert request.client_ip == "127.0.0.1" assert response.body == b"" headers = {"X-Forwarded-For": "127.0.0.1, 127.0.1.2"}