Mỗi máy trên mạng có định danh duy nhất. Giống như bạn viết địa chỉ trên thư để gửi bưu chính, máy tính dùng định danh duy nhất để gửi dữ liệu đến máy tính cụ thể trên mạng. Hầu hết mạng ngày nay, bao gồm tất cả máy tính trên internet, dùng giao thức TCP/IP làm tiêu chuẩn giao tiếp. Trong giao thức TCP/IP, định danh duy nhất cho máy tính gọi là địa chỉ IP của nó.
Sử dụng HttpRequest.UserHostAddress property
Ví dụ trong Controller
using System.Web.Mvc;
namespace DemoMvcApplication.Controllers {
public class HomeController : Controller {
public string Index() {
string ipAddress = Request.UserHostAddress;
return ipAddress;
}
}
}
Nếu muốn lấy IP address bên ngoài controller (trong class thường), làm như sau:
using System.Web;
namespace DemoMvcApplication.Helpers {
public static class DemoHelperClass {
public static string GetIPAddress() {
string ipAddress = HttpContext.Current.Request.UserHostAddress;
return ipAddress;
}
}
}
Ví dụ dùng ServerVariables
using System.Web.Mvc;
namespace DemoMvcApplication.Controllers {
public class HomeController : Controller {
public string Index() {
string ipAddress = Request.ServerVariables["REMOTE_ADDR"];
return ipAddress;
}
}
}
Output
Vì chạy local, IP address của localhost là ::1. Tên localhost thường resolve đến IPv4 loopback 127.0.0.1, và IPv6 loopback ::1
Xử lý Proxy / Load Balancer ( quan trọng )
Khi ứng dụng chạy sau proxy, load balancer, hoặc Azure/AWS, Request.UserHostAddress sẽ trả về IP của proxy, không phải client thực. Cần kiểm tra header X-Forwarded-For:
public static string GetClientIpAddress(HttpRequestBase request) {
// Kiểm tra X-Forwarded-For header (có thể chứa nhiều IP, cách nhau bởi dấu phẩy)
string ip = request.Headers["X-Forwarded-For"];
if (!string.IsNullOrEmpty(ip)) {
// Lấy IP đầu tiên (client gốc)
ip = ip.Split(',')[0].Trim();
} else {
// Fallback đến REMOTE_ADDR hoặc UserHostAddress
ip = request.ServerVariables["HTTP_X_FORWARDED_FOR"]
?? request.ServerVariables["REMOTE_ADDR"]
?? request.UserHostAddress;
}
return ip;
}
// Trong ASP.NET Core (HttpContext)
public static string GetClientIpAddress(HttpContext context) {
var ip = context.Request.Headers["X-Forwarded-For"].FirstOrDefault();
if (!string.IsNullOrEmpty(ip)) {
ip = ip.Split(',')[0].Trim();
} else {
ip = context.Connection.RemoteIpAddress?.ToString();
}
return ip;
}
IPv4 vs IPv6
public static string GetIpV4Address(HttpContext context) {
var ip = GetClientIpAddress(context);
// Nếu là IPv6 loopback (::1) hoặc IPv4-mapped IPv6 (::ffff:127.0.0.1)
if (IPAddress.TryParse(ip, out var address)) {
if (address.IsIPv4MappedToIPv6) {
return address.MapToIPv4().ToString();
}
if (address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetworkV6) {
// Có thể convert hoặc trả về nguyên bản
}
}
return ip;
}
Lưu ý bảo mật
- Header X-Forwarded-For có thể bị spoof - chỉ tin cậy nếu bạn kiểm soát proxy/load balancer
- Cấu hình proxy để strip/validate header này
- Trong Azure/AWS, dùng middleware ForwardedHeadersOptions
// ASP.NET Core - Configure Forwarded Headers services.Configure(options => { options.ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto; options.KnownNetworks.Clear(); // Trust all proxies (cẩn thận production) options.KnownProxies.Clear(); });