C# 获取用户IP地址(转载)

【ASP.NET开发】获取客户端IP地址 via C#

  说明:本文中的内容是我综合博客园上的博文和MSDN讨论区的资料,再通过自己的实际测试而得来,属于自己原创的内容说实话很少,写这一篇是为了记录自己在项目中做过的事情,同时也想抛砖引玉。参考的博文及其作者在下文均有提及。待到自己以后对HTTP、TCP/IP等知识学深入了,一定再来这里深入讨论这个内容。

一、名词

  首先说一下接下来要讲到的一些名词。

  在Web开发中,我们大多都习惯使用HTTP请求头中的某些属性来获取客户端的IP地址,常见的属性是REMOTE_ADDRHTTP_VIAHTTP_X_FORWARDED_FOR。

  这三个属性的含义,大概是如此:(摘自网上,欢迎指正)

  REMOTE_ADDR:该属性的值是客户端跟服务器“握手”时候的IP。如果使用了“匿名代理”,REMOTE_ADDR将显示代理服务器的IP。

  X-Forwarded-For:是用来识别通过HTTP代理或负载均衡方式连接到Web服务器的客户端最原始的IP地址的HTTP请求头字段。

    XFF的有效性依赖于代理服务器提供的连接原始IP地址的真实性,因此, XFF的有效使用应该保证代理服务器是可信的, 比如可以通过建立可信服务器白名单的方式。

  这一HTTP头一般格式如下:

  X-Forwarded-For: client1, proxy1, proxy2

  其中的值通过逗号+空格,把多个IP地址区分开, 最左边(client1)是最原始客户端的IP地址, 代理服务器每成功收到一个请求,就把请求来源IP地址添加到右边。 在上面这个例子中,这个请求成功通过了三台代理服务器:proxy1, proxy2 及 proxy3。请求由client1发出,到达了proxy3(proxy3可能是请求的终点)。请求刚从client1中发出时,XFF是空的,请求被发往proxy1;通过proxy1的时候,client1被添加到XFF中,之后请求被发往proxy2;通过proxy2的时候,proxy1被添加到XFF中,之后请求被发往proxy3;通过proxy3时,proxy2被添加到XFF中,之后请求的的去向不明,如果proxy3不是请求终点,请求会被继续转发。

  鉴于伪造这一字段非常容易,应该谨慎使用X-Forwarded-For字段。正常情况下XFF中最后一个IP地址是最后一个代理服务器的IP地址, 这通常是一个比较可靠的信息来源。

  (另附维基中对X-Forwarded-For的完整介绍:http://zh.wikipedia.org/wiki/X-Forwarded-For

  至于在使用这些属性的时候,属性的值是什么,网上查到一份这样的博文:获取用户IP地址的三个属性的区别(原作者不详)。

  

  而在ASP.NET中,还可以通过另外一种方式获得客户端的IP地址,那就是通过Request对象中的UserHostAddress属性。在MSDN Library中,对这个属性是这样解释的:属性值是远程客户端的 IP 地址。

  如果客户端使用了代理服务器,那么Request.UserHostAddress属性获得的就是代理服务器的IP地址。

二、方法

  好了,讲了那么多概念性的东西,咱们来讲一下实现的方法。

  网上大多数方法的思路是:如果有代理IP,则优先获取代理IP,否则获取连接客户端的IP;或者调转过来,先获取连接客户端的IP,如获取失败,则获取代理IP。

  以下方法参考博文asp.net获取客户端IP (作者comeonfyz)

-----------------------------------------------------------------------------------------------------------

/// <summary>
/// 获取客户端IP地址
/// </summary>
/// <returns>若失败则返回回送地址</returns>
public static string GetIP()
{
    //如果客户端使用了代理服务器,则利用HTTP_X_FORWARDED_FOR找到客户端IP地址
    string userHostAddress = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString().Split(‘,‘)[0].Trim();
    //否则直接读取REMOTE_ADDR获取客户端IP地址
    if (string.IsNullOrEmpty(userHostAddress))
    {
        userHostAddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
    }
    //前两者均失败,则利用Request.UserHostAddress属性获取IP地址,但此时无法确定该IP是客户端IP还是代理IP
    if (string.IsNullOrEmpty(userHostAddress))
    {
        userHostAddress = HttpContext.Current.Request.UserHostAddress;
    }
    //最后判断获取是否成功,并检查IP地址的格式(检查其格式非常重要)
    if (!string.IsNullOrEmpty(userHostAddress) && IsIP(userHostAddress))
    {
        return userHostAddress;
    }
    return "127.0.0.1";
}

/// <summary>
/// 检查IP地址格式
/// </summary>
/// <param name="ip"></param>
/// <returns></returns>
public static bool IsIP(string ip)
{
    return System.Text.RegularExpressions.Regex.IsMatch(ip, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$");
}

-----------------------------------------------------------------------------------------------------------

  但是这样做有一个很严重的缺陷,那就是如大牛Kingthy在其博文 使用HTTP_X_FORWARDED_FOR获取客户端IP的严重后果   中所说的,"HTTP_X_FORWARDED_FOR"这个值是通过获取HTTP头的"X_FORWARDED_FOR"属性取得的,恶意破坏者可以很轻松地伪造IP地址;而且上文特别提到过,XFF的有效性依赖于代理服务器提供的连接原始IP地址的真实性,因此, XFF的有效使用应该保证代理服务器是可信的。但是作为开发者,我们既不知道用户的IP地址的真实性,更是难以分辨代理服务器的可信性。

  因此,综合各个方面的资料,我个人的想法与大牛Kingthy一样:无视代理

-----------------------------------------------------------------------------------------------------------

 1     /// <summary>
 2     /// 获取客户端IP地址(无视代理)
 3     /// </summary>
 4     /// <returns>若失败则返回回送地址</returns>
 5     public static string GetHostAddress()
 6     {
 7         string userHostAddress = HttpContext.Current.Request.UserHostAddress;
 8
 9         if (string.IsNullOrEmpty(userHostAddress))
10         {
11             userHostAddress = HttpContext.Current.Request.ServerVariables["REMOTE_ADDR"];
12         }
13
14         //最后判断获取是否成功,并检查IP地址的格式(检查其格式非常重要)
15         if (!string.IsNullOrEmpty(userHostAddress) && IsIP(userHostAddress))
16         {
17             return userHostAddress;
18         }
19         return "127.0.0.1";
20     }
21
22     /// <summary>
23     /// 检查IP地址格式
24     /// </summary>
25     /// <param name="ip"></param>
26     /// <returns></returns>
27     public static bool IsIP(string ip)
28     {
29         return System.Text.RegularExpressions.Regex.IsMatch(ip, @"^((2[0-4]\d|25[0-5]|[01]?\d\d?)\.){3}(2[0-4]\d|25[0-5]|[01]?\d\d?)$");
30     }

-----------------------------------------------------------------------------------------------------------

三、总结  

  无视代理服务器肯定不是最好的解决方案,如果项目需求明确说要客户端的真实地址,那肯定就不能无视代理服务器了。

  另外,我也向Artech大牛请教过这方面的问题,他虽然对这些没有深入的研究,但是他也认为没有一种IP获取方式是完全值得信赖的,因为这是TCP/IP协议本身决定的。

  附上Artech大牛给我的一份资料,分享分享。http://www.symantec.com/connect/articles/ip-spoofing-introduction

 

转载来源:https://www.cnblogs.com/stay-foolish/archive/2012/05/01/2475071.html

原文地址:https://www.cnblogs.com/hao-1234-1234/p/8776522.html

时间: 2024-11-16 21:22:33

C# 获取用户IP地址(转载)的相关文章

Flask框架获取用户IP地址的方法

本文实例讲述了python使用Flask框架获取用户IP地址的方法.分享给大家供大家参考.具体如下: 下面的代码包含了html页面和python代码,非常详细,如果你正使用Flask,也可以学习一下最基本的Flask使用方法. python代码如下: from flask import Flask, render_template, request # Initialize the Flask application app = Flask(__name__) # Default route,

获取用户Ip地址通用方法

这个来自一些项目中,获取用户Ip,进行用户操作行为的记录,是常见并且经常使用的. 一般朋友,都会看到如下通用获取IP地址方法. 1 public static function getIp() 2 { 3 if ($HTTP_SERVER_VARS["HTTP_X_FORWARDED_FOR"]) 4 { 5 $ip = $HTTP_SERVER_VARS["HTTP_X_FORWARDED_FOR"]; 6 } 7 elseif ($HTTP_SERVER_VAR

【用jQuery来判断浏览器的类型】及【javascript获取用户ip地址】

用jQuery来判断浏览器的类型,主要是使用$.browser这个工具类,使用方法: $.browser.['浏览器关键字'] //谷歌浏览器.360浏览器等其他一些浏览器,没有专门的判断 function appInfo() { var bro = $.browser; var binfo = ""; if (bro.msie) { binfo = "Microsoft Internet Explorer " + bro.version; // bro.versi

用户登录时,获取用户ip地址

使用django来获取用户访问的IP地址,如果用户是正常情况下通过request.META['REMOTE_ADDR']  可以获得用户的IP地址.但是有些网站服务器会使用ngix等代理http,或者是该网站做了负载均衡,导致使用remote_addr抓取到的是1270.0.1,这时使用HTTP_X_FORWARDED_FOR才获得是用户的真实IP. 推荐使用以下代码 if request.META.has_key('HTTP_X_FORWARDED_FOR'): ip = request.ME

获取用户IP地址

// <summary> /// 取得客户端真实IP.如果有代理则取第一个非内网地址 /// by flower.b /// </summary> public static string IPAddress { get { string result = String.Empty; result = HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]; if (result !

Haproxy配置支持https获取用户IP地址

global log 127.0.0.1 local0 chroot /var/lib/haproxy #chroot运行路径 pidfile /var/run/haproxy.pid #haproxy 进程PID文件 maxconn 65535 #默认最大连接数,需考虑ulimit-n限制 user haproxy group haproxy daemon #以后台形式运行harpoxy tune.ssl.default-dh-param 2048 ssl-server-verify none

获取用户ip地址,为什么获取不到代理过之后的

<%@ page language="java" contentType="text/html; charset=UTF-8"     pageEncoding="UTF-8" import="org.apache.commons.lang3.StringUtils;"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN&q

C#获取真实IP地址实现方法

通常来说,大家获取用户IP地址常用的方法是: 1 string IpAddress = ""; 2 if((HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]!=null 3 && HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] !=String.Empty)

C#如何获取真实IP地址

大家获取用户IP地址常用的方法是 C# 代码   复制 string IpAddress = ""; if((HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"]!=null && HttpContext.Current.Request.ServerVariables["HTTP_X_FORWARDED_FOR"] !=String.Empty) )