วิธีรับที่อยู่ IP ของลูกค้าของผู้ใช้ใน ASP.NET?


387

เราต้องRequest.UserHostAddressได้รับที่อยู่ IP ใน ASP.NET แต่โดยปกติจะเป็นที่อยู่ IP ของ ISP ของผู้ใช้ไม่ใช่ที่อยู่ IP ของเครื่องของผู้ใช้ที่คลิกลิงค์ ฉันจะรับที่อยู่ IP จริงได้อย่างไร

ตัวอย่างเช่นในโปรไฟล์ผู้ใช้ Stack Overflow คือ: "กิจกรรมบัญชีล่าสุด: 4 ชั่วโมงที่ผ่านมาจาก 86.123.127.8"แต่ที่อยู่ IP ของเครื่องของฉันแตกต่างกันเล็กน้อย Stack Overflow รับที่อยู่นี้ได้อย่างไร

ในบางระบบเว็บจะมีการตรวจสอบที่อยู่ IP เพื่อวัตถุประสงค์บางอย่าง ตัวอย่างเช่นด้วยที่อยู่ IP ที่แน่นอนผู้ใช้สามารถมีเพียง 5 คลิกที่ลิงค์ดาวน์โหลดทุก ๆ 24 ชั่วโมงหรือไม่ ที่อยู่ IP นี้ควรไม่ซ้ำกันไม่ใช่สำหรับ ISP ที่มีลูกค้าหรือผู้ใช้อินเทอร์เน็ตจำนวนมาก

ฉันเข้าใจดีหรือไม่


4
พวกเขามักจะทำสิ่งเดียวกันและไม่ทำงานอย่างถูกต้องสำหรับที่อยู่ IP ที่ใช้ร่วมกัน สามารถทำได้ไม่มากนักในพื้นที่นี้
Mehrdad Afshari

ปัญหาที่คุณพยายามแก้ไขที่นี่ทำไมคุณคิดว่าคุณต้องการที่อยู่ IP
Steve

3
ฉันมีแอปพลิเคชั่นที่ตรวจสอบการคลิกลิงก์ที่เฉพาะเจาะจงและผู้ใช้ที่ระบุ (ตาม IP) ไม่สามารถคลิกลิงก์มากกว่า 5 ครั้งในหนึ่งวันปัญหาคือว่าถ้า Request.UserHostAddress นั้นมีไว้สำหรับผู้ใช้ที่อยู่ภายใต้ ISP หรือเครือข่ายหรือ ผู้ใช้ที่เฉพาะเจาะจงหรือไม่
Mehdi

คำตอบ:


142

อย่างที่คนอื่นพูดคุณไม่สามารถทำสิ่งที่คุณขอได้ หากคุณอธิบายถึงปัญหาที่คุณพยายามแก้ไขอาจมีคนช่วยได้บ้าง

เช่น

  • คุณกำลังพยายามระบุผู้ใช้ของคุณโดยเฉพาะหรือไม่?
  • คุณสามารถใช้คุกกี้หรือรหัสเซสชันแทนที่อยู่ IP ได้หรือไม่

แก้ไขที่อยู่ที่คุณเห็นบนเซิร์ฟเวอร์ไม่ควรเป็นที่อยู่ของ ISP อย่างที่คุณบอกว่าเป็นช่วงใหญ่ ที่อยู่สำหรับผู้ใช้ตามบ้านบนบรอดแบนด์จะเป็นที่อยู่ที่เราเตอร์ของพวกเขาดังนั้นอุปกรณ์ทุกอย่างในบ้านจะปรากฏที่ด้านนอกเหมือนกัน แต่เราเตอร์ใช้ NAT เพื่อให้แน่ใจว่าปริมาณการใช้งานถูกส่งไปยังอุปกรณ์แต่ละเครื่องอย่างถูกต้อง สำหรับผู้ใช้ที่เข้าถึงจากสภาพแวดล้อมสำนักงานที่อยู่อาจจะเหมือนกันสำหรับผู้ใช้ทั้งหมด เว็บไซต์ที่ใช้ที่อยู่ IP สำหรับรหัสเสี่ยงต่อการทำให้มันผิดมาก - ตัวอย่างที่คุณให้นั้นเป็นเว็บไซต์ที่ดีและมักจะล้มเหลว ตัวอย่างเช่นสำนักงานของฉันอยู่ในสหราชอาณาจักรจุดแตกหัก (ที่ฉัน "ปรากฏ" เป็นบนอินเทอร์เน็ต) อยู่ในประเทศอื่นที่ศูนย์ไอทีหลักของเราอยู่ดังนั้นจากสำนักงานของฉันที่อยู่ IP ของฉันดูเหมือนจะไม่ได้อยู่ในสหราชอาณาจักร ด้วยเหตุนี้ฉันไม่สามารถเข้าถึงเนื้อหาเว็บในสหราชอาณาจักรเท่านั้น เช่น BBC iPlayer) ในเวลาใดก็ตามจะมีคนหลายร้อยหรือหลายพันคนใน บริษัท ของฉันซึ่งดูเหมือนจะเข้าถึงเว็บจากที่อยู่ IP เดียวกัน

เมื่อคุณเขียนรหัสเซิร์ฟเวอร์คุณจะไม่สามารถมั่นใจได้ว่าที่อยู่ IP ที่คุณเห็นนั้นหมายถึงอะไร ผู้ใช้บางคนชอบวิธีนี้ บางคนจงใจใช้พรอกซีหรือ VPN เพื่อทำให้คุณสับสน

เมื่อคุณบอกว่าที่อยู่เครื่องของคุณแตกต่างจากที่อยู่ IP ที่แสดงใน StackOverflow คุณจะทราบที่อยู่เครื่องของคุณได้อย่างไร หากคุณกำลังมองหาการใช้งานในประเทศipconfigหรือสิ่งที่ฉันคาดหวังว่ามันจะแตกต่างกันสำหรับเหตุผลที่ฉันระบุไว้ข้างต้น หากคุณต้องการที่จะตรวจสอบอีกครั้งสิ่งที่โลกภายนอกคิดว่ามีลักษณะที่whatismyipaddress.com/

ลิงก์ Wikipediaนี้ใน NATจะให้ข้อมูลพื้นฐานบางอย่างแก่คุณ


ดังนั้นฉันจึงเข้าใจในแอปพลิเคชันฝั่งเซิร์ฟเวอร์ที่เราไม่แน่ใจเกี่ยวกับที่อยู่ IP มันหมายความว่าการเขียนโปรแกรมฝั่งไคลเอ็นต์เป็นทางออกหรือไม่? คุณหมายถึงตัวอย่างเช่นด้วยรหัส JavaScript บางอย่างที่เราสามารถทำได้ ??
เมห์

12
ไม่นี่จะไร้จุดหมายที่อยู่ IP ที่ลูกค้า "คิดว่า" จะมีอยู่ภายในบ้านหรือที่ทำงานจะไม่มีความหมายในโลกภายนอก เช่นเราเตอร์ที่บ้านส่วนใหญ่แจกที่อยู่ IP ในช่วง 192.168.1.xxx ดังนั้นเครื่องนับพันจึงมีที่อยู่เดียวกันในเครือข่ายของตนเอง
Steve

12
ไม่มันไม่ซ้ำกัน ผู้ใช้สองคนที่อยู่หลังเราเตอร์เดียวกันโดยใช้ NAT จะมีที่อยู่ IP เดียวกัน ฉันคิดว่าคุณจำเป็นต้องอ่านสิ่งนี้ดูลิงค์ในการแก้ไขของฉัน
Steve

1
เหตุใด บริษัท ต่างๆเช่น AWS, Azure ฯลฯ จึงใช้ที่อยู่ ip ในกฎกลุ่มความปลอดภัยและอนุญาตเฉพาะที่อยู่ IP นั้นเพื่อเชื่อมต่อกับ VM

2
@ user5950947: เพราะ Azure คาดว่าคุณจะเป็น บริษัท ที่มีที่อยู่ IP สาธารณะคงที่ มีความปลอดภัยที่จะสมมติว่า บริษัท ของคุณจะเข้าถึงจากที่อยู่ IP สาธารณะเท่านั้นดังนั้นจึงเป็นคุณลักษณะด้านความปลอดภัยที่ดีที่เพิ่มเข้ามา แต่ที่อยู่ IP สามารถปลอมแปลงได้หรือเครือข่ายของคุณอาจถูกแฮ็ก
Deantwo

449

บ่อยครั้งที่คุณต้องการทราบที่อยู่ IP ของบางคนที่เยี่ยมชมเว็บไซต์ของคุณ ในขณะที่ ASP.NET มีหลายวิธีในการทำหนึ่งในวิธีที่ดีที่สุดที่เราเห็นคือการใช้ "HTTP_X_FORWARDED_FOR" ของคอลเลกชัน ServerVariables

นี่คือเหตุผล ...

บางครั้งผู้เยี่ยมชมของคุณอยู่ด้านหลังพร็อกซีเซิร์ฟเวอร์หรือเราเตอร์และมาตรฐานRequest.UserHostAddressจะจับที่อยู่ IP ของพร็อกซีเซิร์ฟเวอร์หรือเราเตอร์เท่านั้น ในกรณีนี้ที่อยู่ IP ของผู้ใช้จะถูกเก็บไว้ในตัวแปรเซิร์ฟเวอร์ ("HTTP_X_FORWARDED_FOR")

ดังนั้นสิ่งที่เราต้องการจะทำคือครั้งแรกที่ตรวจสอบ "HTTP_X_FORWARDED_FOR" ServerVariables("REMOTE_ADDR")และหากที่ว่างแล้วเราก็กลับมา

ในขณะที่วิธีนี้ไม่สามารถจะเข้าใจผิดได้ แต่สามารถนำไปสู่ผลลัพธ์ที่ดีกว่า ด้านล่างเป็นรหัส ASP.NET ใน VB.NET นำมาจากโพสต์บล็อกของ James Crowley "Gotcha: HTTP_X_FORWARDED_FOR คืนค่าที่อยู่ IP หลายรายการ"

ค#

protected string GetIPAddress()
{
    System.Web.HttpContext context = System.Web.HttpContext.Current; 
    string ipAddress = context.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

    if (!string.IsNullOrEmpty(ipAddress))
    {
        string[] addresses = ipAddress.Split(',');
        if (addresses.Length != 0)
        {
            return addresses[0];
        }
    }

    return context.Request.ServerVariables["REMOTE_ADDR"];
}

VB.NET

Public Shared Function GetIPAddress() As String
    Dim context As System.Web.HttpContext = System.Web.HttpContext.Current
    Dim sIPAddress As String = context.Request.ServerVariables("HTTP_X_FORWARDED_FOR")
    If String.IsNullOrEmpty(sIPAddress) Then
        Return context.Request.ServerVariables("REMOTE_ADDR")
    Else
        Dim ipArray As String() = sIPAddress.Split(New [Char]() {","c})
        Return ipArray(0)
    End If
End Function

24
อย่าใช้รหัสนี้เพื่อความปลอดภัยเพราะทุกคนสามารถปลอม HTTP_X_FORWARDED_FOR หรือส่วนหัวที่คล้ายกันได้ ดังนั้นหากคุณใช้สิ่งนี้สำหรับการบันทึกที่เกี่ยวข้องกับความปลอดภัยหรือการตรวจสอบความปลอดภัยผู้โจมตีสามารถข้ามได้อย่างง่ายดาย
ดร. ชั่วร้าย

4
จากการเชื่อมโยงของคุณแต่รหัสของคุณได้รับเป็นครั้งแรกwhat we actually needed to be doing was take the last IP address addresses[0]อันไหนถูกต้อง?
เนลสันโรเธอร์เมล

4
@NelsonRothermel บนพื้นฐานของen.wikipedia.org/wiki/X-Forwarded-For#Formatถ้าคุณต้องการของลูกค้า (แทนที่จะพร็อกซีก่อนหน้านี้) จากนั้นใช้ครั้งแรก
ริชาร์ด

4
@ dr.evil คุณจะเสนออะไรแทน เพราะฉันต้องการตั้งค่าการเข้าถึงบริการ WCF ตาม IP ที่ระบุ
krypru

7
addresses.Length != 0ไม่จำเป็นเพราะมันไม่สามารถเป็น 0
James Wilkins

78

ปรับปรุง: ขอบคุณ Bruno Lopes หากมีที่อยู่ IP หลายรายการอาจจำเป็นต้องใช้วิธีนี้:

    private string GetUserIP()
    {
        string ipList = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

        if (!string.IsNullOrEmpty(ipList))
        {
            return ipList.Split(',')[0];
        }

        return Request.ServerVariables["REMOTE_ADDR"];
    }

3
ดังที่ระบุไว้ในคำตอบอื่น HTTP_X_FORWARDED_FOR สามารถเป็นรายการของ IP ได้โดยคั่นด้วยเครื่องหมายจุลภาค
Bruno Lopes

ในการตอบสนองต่อฟังก์ชั่นฉันเพิ่งได้รับ :: 1 ทุกครั้ง ฉันไม่สามารถรับที่อยู่ IP ที่สมบูรณ์ได้หรือไม่?
farhangdon

1
มันจะกลับมา :: 1 ในโฮสต์ท้องถิ่น ลองใช้กับสภาพแวดล้อมของผลิตภัณฑ์และควรจะใช้ได้
Benny Margalit

1
@farhangdon รหัสต่อไปนี้จะส่งคืนที่อยู่ ip ในโฮสต์ในพื้นที่เป็น @Bat_Programmer เขียนด้านล่างSystem.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).AddressList[1].ToString();
Benny Margalit

อย่าทำอย่างนี้! ระวังอย่าใช้ที่อยู่ IP แรกในรายการ คุณควรข้าม IP พร็อกซีที่รู้จักเท่านั้นที่เริ่มต้นที่รายการขวาสุดเพื่อหลีกเลี่ยงการโจมตีจากคนกลางและการปลอมแปลงส่วนหัว
Jpsy

24

ถ้า c # ดูวิธีนี้ง่ายมาก

string clientIp = (Request.ServerVariables["HTTP_X_FORWARDED_FOR"] ?? 
                   Request.ServerVariables["REMOTE_ADDR"]).Split(',')[0].Trim();

8
หากตัวแปรเซิร์ฟเวอร์ทั้งสองสามารถเป็นโมฆะก็สามารถโยนข้อยกเว้น
Michael Freidgeim

คำขออ้างอิงที่นี่คืออะไร I
Server

23

คุณพิจารณาที่อยู่ IP ของผู้ใช้อื่น ๆ หากคุณต้องการที่อยู่ IP ของอะแดปเตอร์เครือข่ายฉันกลัวว่าจะไม่มีวิธีการทำเช่นนี้ในเว็บแอป หากผู้ใช้ของคุณอยู่หลัง NAT หรือสิ่งอื่น ๆ คุณจะไม่สามารถรับ IP ได้

อัปเดต : ในขณะที่มีเว็บไซต์ที่ใช้ IP เพื่อ จำกัด ผู้ใช้ (เช่น Rapidshare) พวกเขาทำงานไม่ถูกต้องในสภาพแวดล้อม NAT


22

ฉันคิดว่าฉันควรแบ่งปันประสบการณ์ของฉันกับคุณทั้งหมด ฉันเห็นในบางสถานการณ์REMOTE_ADDRจะไม่ให้สิ่งที่คุณต้องการ ตัวอย่างเช่นหากคุณมี Load Balancer อยู่เบื้องหลังและหากคุณพยายามรับ IP ของลูกค้าคุณจะประสบปัญหา ฉันตรวจสอบด้วยซอฟต์แวร์กำบัง IP ของฉันและฉันยังตรวจสอบกับเพื่อนร่วมงานของฉันที่อยู่ในทวีปต่าง ๆ นี่คือทางออกของฉัน

เมื่อฉันต้องการทราบ IP ของลูกค้าฉันพยายามเลือกหลักฐานที่เป็นไปได้ทั้งหมดเพื่อที่ฉันจะได้ทราบว่าพวกเขามีลักษณะเฉพาะหรือไม่:

ที่นี่ฉันพบเซิร์ฟเวอร์สำรองอื่นที่สามารถช่วยคุณได้ทั้งหมดหากคุณต้องการรับ IP ที่แน่นอนของฝั่งไคลเอ็นต์ ดังนั้นฉันใช้: HTTP_X_CLUSTER_CLIENT_IP

HTTP_X_CLUSTER_CLIENT_IPทำให้คุณได้รับ IP ที่แน่นอนของลูกค้าเสมอ ในกรณีใด ๆ หากมันไม่ได้ให้คุณค่าแก่คุณคุณควรมองหาHTTP_X_FORWARDED_FORเพราะมันเป็นตัวเลือกที่ดีที่สุดอันดับที่สองเพื่อให้คุณได้รับ IP ไคลเอนต์และจากนั้นREMOTE_ADDR var ซึ่งอาจหรืออาจจะไม่คืนค่า IP ให้ฉัน สามคือสิ่งที่ฉันพบสิ่งที่ดีที่สุดในการตรวจสอบพวกเขา

ฉันหวังว่านี่จะช่วยให้ผู้ชายบางคน


ต้องบอกว่าส่วนหัว http_x _... สามารถปลอมแปลงความเคารพได้ง่ายกับตัวแปร remote_addr และดังนั้น remote_addr ยังคงเป็นแหล่งที่เชื่อถือได้มากที่สุดสำหรับที่อยู่ IP ของลูกค้า
Ciro Corvino

1
@CiroCorvino คุณถูกต้อง แต่เมื่อคุณมีเว็บไซต์ของคุณโฮสต์บนเซิร์ฟเวอร์ที่ทำงานอยู่หลัง Load Balancer (ดังที่ฉันได้กล่าวถึงแล้วในโพสต์ของฉัน) จากนั้น remote_addr จะไม่ให้ IP ที่คุณต้องการ ฉันมีประสบการณ์สิ่งที่คุณพูด แต่เมื่อฉันขุดในการแก้ปัญหาสิ่งที่ฉันได้กล่าวถึงได้ผลดีที่สุดสำหรับฉัน
KMX

ขออภัย @KMX มีผลฉันยังใช้การรวมกันของ remote_addr และ http_x_forwarded เพื่ออนุมานบางสมมติฐานเกี่ยวกับที่มาของคำขอ หากคุณแก้ไขโพสต์ของฉันฉันอัพเดตการลงคะแนนของฉัน
Ciro Corvino

15

คุณสามารถใช้ได้:

System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).AddressList.GetValue(0).ToString();

1
ขอบคุณสำหรับฉันนี่เป็นวิธีเดียวที่จะคืนค่า IP ของฉันบนโฮสต์ท้องถิ่น
Benny Margalit

จริงๆแล้วสิ่งที่ฉันเคยได้รับที่อยู่ ip ของท้องถิ่นคือSystem.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).AddressList[1].ToString();
Benny Margalit

1
รหัสนี้ใช้ได้กับฉันเท่านั้นและฉันสามารถรับ IPv6 และ IPv4 โดยใช้ GetValue (0) และ GetValue (1) ตามลำดับ ขอบคุณโหวตแล้ว!
Raj Baral

อย่างไรก็ตามฉันได้รับข้อผิดพลาดในขณะที่ดำเนินการในซอ Request for the permission of type 'System.Net.DnsPermission, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' failed.
vibs2006

OP ขอวิธีรับ IP ของผู้ใช้เว็บระยะไกลไม่ใช่ที่อยู่ของ localhost
t.durden

13

ที่อยู่ IP เป็นส่วนหนึ่งของเลเยอร์เครือข่ายใน "เซเว่นสแต็คเจ็ดชั้น" เลเยอร์เครือข่ายสามารถทำสิ่งที่มันต้องการจะทำกับที่อยู่ IP นั่นคือสิ่งที่เกิดขึ้นกับพร็อกซีเซิร์ฟเวอร์, NAT, รีเลย์หรืออะไรก็ตาม

ชั้น Application ไม่ควรขึ้นอยู่กับที่อยู่ IP แต่อย่างใด โดยเฉพาะอย่างยิ่งที่อยู่ IP ไม่ได้หมายถึงตัวบ่งชี้ของสิ่งอื่นใดนอกจาก idenfitier ของปลายด้านหนึ่งของการเชื่อมต่อเครือข่าย ทันทีที่การเชื่อมต่อถูกปิดคุณควรคาดหวังว่าที่อยู่ IP (ของผู้ใช้รายเดียวกัน) จะเปลี่ยน


1
ทั้งหมดนี้เป็นสิ่งที่ดีและดี แต่คุณจะทำอย่างไรเมื่อลูกค้ารายหนึ่งของระบบหลายผู้เช่าเรียกร้องให้บัญชีผู้ใช้ของพวกเขาสามารถเข้าสู่ระบบได้จากที่อยู่ IP ที่ระบุเท่านั้น
Ronnie Overby

1
จากนั้นพวกเขาจะต้องบอกคุณว่าที่อยู่ IP ของเซิร์ฟเวอร์ของคุณจะเห็น หากพวกเขาต้องการมีที่อยู่เฉพาะพวกเขาจะไม่สามารถอยู่หลัง NAT หรือที่คล้ายกัน
John Saunders

@ RonnieOver โดยฉันอยู่ในสถานการณ์เดียวกัน ฉันจำเป็นต้องรู้ว่าพวกเขากำลังเชื่อมต่อกับ IP ใดและต้องอยู่ในรายการที่อนุญาตของฉัน จากนั้นแอปสามารถเปิดหรือปิดฟังก์ชันการทำงานบางอย่างตาม IP ของพวกเขา นี่คือสิ่งที่ลูกค้าต้องการ
t.durden

10

การตอบสนองทั้งหมดคำนึงถึงส่วนหัวที่ไม่ได้มาตรฐาน แต่พบได้บ่อยมาก X-Forwarded-ForมีForwardedส่วนหัวที่เป็นมาตรฐานซึ่งแยกออกได้ยากกว่าเล็กน้อย ตัวอย่างบางส่วนมีดังนี้:

Forwarded: for="_gazonk"
Forwarded: For="[2001:db8:cafe::17]:4711"
Forwarded: for=192.0.2.60;proto=http;by=203.0.113.43
Forwarded: for=192.0.2.43, for=198.51.100.17

ฉันได้เขียนคลาสที่คำนึงถึงส่วนหัวทั้งสองนี้เมื่อพิจารณาที่อยู่ IP ของลูกค้า

using System;
using System.Web;

namespace Util
{
    public static class IP
    {
        public static string GetIPAddress()
        {
            return GetIPAddress(new HttpRequestWrapper(HttpContext.Current.Request));
        }

        internal static string GetIPAddress(HttpRequestBase request)
        {
            // handle standardized 'Forwarded' header
            string forwarded = request.Headers["Forwarded"];
            if (!String.IsNullOrEmpty(forwarded))
            {
                foreach (string segment in forwarded.Split(',')[0].Split(';'))
                {
                    string[] pair = segment.Trim().Split('=');
                    if (pair.Length == 2 && pair[0].Equals("for", StringComparison.OrdinalIgnoreCase))
                    {
                        string ip = pair[1].Trim('"');

                        // IPv6 addresses are always enclosed in square brackets
                        int left = ip.IndexOf('['), right = ip.IndexOf(']');
                        if (left == 0 && right > 0)
                        {
                            return ip.Substring(1, right - 1);
                        }

                        // strip port of IPv4 addresses
                        int colon = ip.IndexOf(':');
                        if (colon != -1)
                        {
                            return ip.Substring(0, colon);
                        }

                        // this will return IPv4, "unknown", and obfuscated addresses
                        return ip;
                    }
                }
            }

            // handle non-standardized 'X-Forwarded-For' header
            string xForwardedFor = request.Headers["X-Forwarded-For"];
            if (!String.IsNullOrEmpty(xForwardedFor))
            {
                return xForwardedFor.Split(',')[0];
            }

            return request.UserHostAddress;
        }
    }
}

ด้านล่างคือการทดสอบหน่วยที่ฉันใช้ในการตรวจสอบความถูกต้องของโซลูชัน:

using System.Collections.Specialized;
using System.Web;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace UtilTests
{
    [TestClass]
    public class IPTests
    {
        [TestMethod]
        public void TestForwardedObfuscated()
        {
            var request = new HttpRequestMock("for=\"_gazonk\"");
            Assert.AreEqual("_gazonk", Util.IP.GetIPAddress(request));
        }

        [TestMethod]
        public void TestForwardedIPv6()
        {
            var request = new HttpRequestMock("For=\"[2001:db8:cafe::17]:4711\"");
            Assert.AreEqual("2001:db8:cafe::17", Util.IP.GetIPAddress(request));
        }

        [TestMethod]
        public void TestForwardedIPv4()
        {
            var request = new HttpRequestMock("for=192.0.2.60;proto=http;by=203.0.113.43");
            Assert.AreEqual("192.0.2.60", Util.IP.GetIPAddress(request));
        }

        [TestMethod]
        public void TestForwardedIPv4WithPort()
        {
            var request = new HttpRequestMock("for=192.0.2.60:443;proto=http;by=203.0.113.43");
            Assert.AreEqual("192.0.2.60", Util.IP.GetIPAddress(request));
        }

        [TestMethod]
        public void TestForwardedMultiple()
        {
            var request = new HttpRequestMock("for=192.0.2.43, for=198.51.100.17");
            Assert.AreEqual("192.0.2.43", Util.IP.GetIPAddress(request));
        }
    }

    public class HttpRequestMock : HttpRequestBase
    {
        private NameValueCollection headers = new NameValueCollection();

        public HttpRequestMock(string forwarded)
        {
            headers["Forwarded"] = forwarded;
        }

        public override NameValueCollection Headers
        {
            get { return this.headers; }
        }
    }
}

9

หากคุณใช้ CloudFlare คุณสามารถลองใช้วิธีการขยายนี้:

public static class IPhelper
{
    public static string GetIPAddress(this HttpRequest Request)
    {
        if (Request.Headers["CF-CONNECTING-IP"] != null) return Request.Headers["CF-CONNECTING-IP"].ToString();

        if (Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null) return Request.ServerVariables["HTTP_X_FORWARDED_FOR"].ToString();

        return Request.UserHostAddress;
    }
}

แล้วก็

string IPAddress = Request.GetIPAddress();

และใช้ F5 หรือ Palo Alto?
Kiquenet


7

สิ่งที่คุณสามารถทำได้คือเก็บ IP ของเราเตอร์ของผู้ใช้ของคุณและ IP ที่ส่งต่อและพยายามทำให้มันน่าเชื่อถือโดยใช้ทั้ง IP [สาธารณะภายนอกและภายในส่วนตัว] แต่อีกครั้งหลังจากไคลเอนต์บางวันอาจได้รับมอบหมาย IP ภายในใหม่จากเราเตอร์ แต่มันจะมีความน่าเชื่อถือมากขึ้น


5

เมื่อรวมคำตอบจาก@Tonyกับ@mangokunฉันได้สร้างวิธีการต่อไปนี้:

public static class RequestExtensions
{
    public static string GetIPAddress(this HttpRequest Request)
    {
        if (Request.Headers["CF-CONNECTING-IP"] != null) return Request.Headers["CF-CONNECTING-IP"].ToString();

        if (Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null)
        {
            string ipAddress = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];

            if (!string.IsNullOrEmpty(ipAddress))
            {
                string[] addresses = ipAddress.Split(',');
                if (addresses.Length != 0)
                {
                    return addresses[0];
                }
            }
        }

        return Request.UserHostAddress;
    }
}

ทำไมคุณถึงใช้HTTP_X_FORWARDED_FORแต่ไม่X_FORWARDED_FOR? พวกเขาเหมือนกันหรือไม่
Igor Yalovoy

3

ใช้ในไฟล์ Ashx

public string getIP(HttpContext c)
{
    string ips = c.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
    if (!string.IsNullOrEmpty(ips))
    {
        return ips.Split(',')[0];
    }
    return c.Request.ServerVariables["REMOTE_ADDR"];
}

2
public static class Utility
{
    public static string GetClientIP(this System.Web.UI.Page page)
    {
        string _ipList = page.Request.Headers["CF-CONNECTING-IP"].ToString();
        if (!string.IsNullOrWhiteSpace(_ipList))
        {
            return _ipList.Split(',')[0].Trim();
        }
        else
        {
            _ipList = page.Request.ServerVariables["HTTP_X_CLUSTER_CLIENT_IP"];
            if (!string.IsNullOrWhiteSpace(_ipList))
            {
                return _ipList.Split(',')[0].Trim();
            }
            else
            {
                _ipList = page.Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
                if (!string.IsNullOrWhiteSpace(_ipList))
                {
                    return _ipList.Split(',')[0].Trim();
                }
                else
                {
                    return page.Request.ServerVariables["REMOTE_ADDR"].ToString().Trim();
                }
            }
        }
    }
}

ใช้;

string _ip = this.GetClientIP();


-1

สวัสดีพวกคุณส่วนใหญ่รหัสที่คุณจะพบจะส่งคืนที่อยู่ IP ของเซิร์ฟเวอร์ของคุณไม่ใช่ที่อยู่ IP ของลูกค้าอย่างไรก็ตามรหัสนี้จะส่งคืนที่อยู่ IP ของไคลเอ็นต์ที่ถูกต้องให้ทดลองใช้ สำหรับข้อมูลเพิ่มเติมเพียงตรวจสอบเรื่องนี้

https://www.youtube.com/watch?v=Nkf37DsxYjI

สำหรับการรับที่อยู่ IP ของคุณโดยใช้จาวาสคริปต์คุณสามารถใช้วางรหัสนี้ไว้ในแท็กสคริปต์ของคุณ

<script>
    var RTCPeerConnection = /*window.RTCPeerConnection ||*/
     window.webkitRTCPeerConnection || window.mozRTCPeerConnection;

         if (RTCPeerConnection) (function () {
             var rtc = new RTCPeerConnection({ iceServers: [] });
             if (1 || window.mozRTCPeerConnection) {      
                 rtc.createDataChannel('', { reliable: false });
             };

             rtc.onicecandidate = function (evt) {

                 if (evt.candidate)
                     grepSDP("a=" + evt.candidate.candidate);
             };
             rtc.createOffer(function (offerDesc) {
                 grepSDP(offerDesc.sdp);
                 rtc.setLocalDescription(offerDesc);
             }, function (e) { console.warn("offer failed", e); });


             var addrs = Object.create(null);
             addrs["0.0.0.0"] = false;
             function updateDisplay(newAddr) {
                 if (newAddr in addrs) return;
                 else addrs[newAddr] = true;
                 var displayAddrs = Object.keys(addrs).filter(function
(k) { return addrs[k]; });
                 document.getElementById('list').textContent =
displayAddrs.join(" or perhaps ") || "n/a";
             }

             function grepSDP(sdp) {
                 var hosts = [];
                 sdp.split('\r\n').forEach(function (line) { 
                     if (~line.indexOf("a=candidate")) {   
                         var parts = line.split(' '),   
                             addr = parts[4],
                             type = parts[7];
                         if (type === 'host') updateDisplay(addr);
                     } else if (~line.indexOf("c=")) {      
                         var parts = line.split(' '),
                             addr = parts[2];
                         updateDisplay(addr);
                     }
                 });
             }
         })(); else
         {
             document.getElementById('list').innerHTML = "<code>ifconfig| grep inet | grep -v inet6 | cut -d\" \" -f2 | tail -n1</code>";
             document.getElementById('list').nextSibling.textContent = "In Chrome and Firefox your IP should display automatically, by the power of WebRTCskull.";

         }




</script>
<body>
<div id="list"></div>
</body>

และสำหรับการรับที่อยู่ IP สาธารณะของคุณคุณสามารถใช้วางรหัสนี้ไว้ในแท็กสคริปต์ของคุณ

  function getIP(json) {
    document.write("My public IP address is: ", json.ip);
  }


<script type="application/javascript" src="https://api.ipify.org?format=jsonp&callback=getIP"></script>


-7

ลอง:

using System.Net;

public static string GetIpAddress()  // Get IP Address
{
    string ip = "";     
    IPHostEntry ipEntry = Dns.GetHostEntry(GetCompCode());
    IPAddress[] addr = ipEntry.AddressList;
    ip = addr[2].ToString();
    return ip;
}
public static string GetCompCode()  // Get Computer Name
{   
    string strHostName = "";
    strHostName = Dns.GetHostName();
    return strHostName;
}

นี่จะส่งคืนที่อยู่ IP ของเซิร์ฟเวอร์
Sreekumar P

มันเกี่ยวกับ asp.net ซึ่งเป็นเว็บแอปพลิเคชันซึ่งทำงานบนเซิร์ฟเวอร์ไม่ใช่ในคอมพิวเตอร์ของผู้ใช้
doekman
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.