| | | 1 | | using Microsoft.AspNetCore.Http; |
| | | 2 | | |
| | | 3 | | namespace ArturRios.Util.WebApi.Extensions; |
| | | 4 | | |
| | | 5 | | /// <summary>Extension methods for identifying the client that made the current request.</summary> |
| | | 6 | | public static class HttpContextClientExtensions |
| | | 7 | | { |
| | | 8 | | /// <param name="context">The current HTTP context.</param> |
| | | 9 | | extension(HttpContext context) |
| | | 10 | | { |
| | | 11 | | /// <summary>Gets the IP address of the client that made the request, from |
| | | 12 | | /// <see cref="ConnectionInfo.RemoteIpAddress"/>. An IPv4 address carried as IPv6 (<c>::ffff:203.0.113.7</c>) |
| | | 13 | | /// comes back in its IPv4 form.</summary> |
| | | 14 | | /// <remarks>Behind a reverse proxy or load balancer this is the proxy's address. Configure ASP.NET Core's |
| | | 15 | | /// <c>ForwardedHeadersOptions</c> with the proxies you trust (the standard middlewares run |
| | | 16 | | /// <c>UseForwardedHeaders</c> first), so the address is taken from <c>X-Forwarded-For</c>. The header is not |
| | | 17 | | /// read here directly, since any client can forge it.</remarks> |
| | | 18 | | /// <returns>The client's IP address, or <see langword="null"/> when the server doesn't know it (for example on |
| | | 19 | | /// an in-memory test server).</returns> |
| | | 20 | | public string? GetClientIpAddress() |
| | | 21 | | { |
| | 34 | 22 | | var address = context.Connection.RemoteIpAddress; |
| | | 23 | | |
| | 34 | 24 | | if (address is null) |
| | | 25 | | { |
| | 27 | 26 | | return null; |
| | | 27 | | } |
| | | 28 | | |
| | 7 | 29 | | return (address.IsIPv4MappedToIPv6 ? address.MapToIPv4() : address).ToString(); |
| | | 30 | | } |
| | | 31 | | } |
| | | 32 | | } |