extractClientIP

Signature

def extractClientIP: Directive1[RemoteAddress]

Description

Provides the value of the X-Forwarded-For or X-Real-IP header. If neither of those is found it will fall back to the value of the synthetic RemoteAddress header (akka.http.server.remote-address-header setting is on) or the value of the AttributeKeys.remoteAddressAttributeKeys.remoteAddress attribute (if the akka.http.server.remote-address-attribute setting is on)

If no valid IP address is encountered, this extractor will return RemoteAddress.Unknown`.

Warning

Clients can send any values in these headers. If the client is not a trusted upstream, the IP address can be malicious. For sensitive operations use the AttributeKeys.remoteAddressAttributeKeys.remoteAddress attribute, or use the specific headers which are known to be set correctly by the infrastructure you do trust.

Example

Scala
val route = extractClientIP { ip =>
  complete("Client's ip is " + ip.toOption.map(_.getHostAddress).getOrElse("unknown"))
}

// tests:
Get("/").withHeaders(`X-Forwarded-For`(RemoteAddress(InetAddress.getByName("192.168.3.12")))) ~> route ~> check {
  responseAs[String] shouldEqual "Client's ip is 192.168.3.12"
}
Java
final Route route = extractClientIP(remoteAddr ->
  complete("Client's IP is " + remoteAddr.getAddress().map(InetAddress::getHostAddress)
    .orElseGet(() -> "unknown"))
);

// tests:
final String ip = "192.168.1.2";
final akka.http.javadsl.model.RemoteAddress remoteAddress =
  akka.http.javadsl.model.RemoteAddress.create(InetAddress.getByName(ip));

final HttpRequest request = HttpRequest.GET("/")
  .addHeader(XForwardedFor.create(remoteAddress)); //

testRoute(route).run(request)
  .assertEntity("Client's IP is " + ip);

testRoute(route).run(HttpRequest.GET("/"))
  .assertEntity("Client's IP is unknown");
Found an error in this documentation? The source code for this page can be found here. Please feel free to edit and contribute a pull request.