本文已参与「新人创作礼」活动,一起开启掘金创作之路
引言
近日,社交网络平台纷纷宣布展示用户的IP属地,这意味着,今后所有用户在网络上发言或评论时,自己在现实生活中的IP归属地将被公开显示,并且用户无法开启或关闭此功能。用户的IP信息,平台是怎么知道的?平台如何通过IP查询属地信息?本文将对这些问题一一阐述,并用Go语言来实现获取IP属地信息。
用户的IP信息,平台是怎么知道的?
其大致流程是这样的:
用户
的手机、电脑等设备必须通过网络运营商(电信、移动等)进行联网服务,这个连接网络的过程中,基站、路由器将为该设备动态分配一个IP
;用户
发布一篇文章或微博,或者进行评论时,就会向平台服务器
发送一个HTTP请求
。而IP
信息,就包含在这个HTTP请求头
里;平台服务器
接收到请求信息,就可以通过HTTP请求(Request请求)
信息解析出该用户的IP
。
在这个过程中,请求信息
只包含IP
,并不包含用户的属地信息
。
另外,对于交互式平台
来说,《互联网交互式服务安全管理要求》(GA 1277.1-2020)的第1部分 基本要求
的第8.3条 日志与用户数据记录
明确,平台必须记录用户的活动、信息发布等操作的IP地址及源端口
。详见:www.beian.gov.cn/portal/down… 。
平台如何通过IP查询到属地信息?
一种方案是请求第三方IP属地信息服务
的API,通过该接口查询用户的IP属地信息
。比如免费的ip-api.com、百度、太平洋等等。但这种方案实现的前提时有API或者数据开放。
另外一种方案是使用离线的IP地址数据库
,该数据库通常是一个文件,甚至可能是cvs
文件、txt
文件。
该数据库一般是由专业人士通过专业技术人工生成,其中记录了大量的IP地址(段)
,并记录了该IP地址(段)
所属的国家
、省份
、城市
、运营商名称
、邮政编码
、经纬度
等信息。
比如Golang有一个比较常用的库叫 Ip2region
,库地址:github.com/lionsoul201… 但这也依赖于API提供的数据,如果API或者数据都不给开放数据时,ip2region将停止数据的更新服务。
免费的IP归属地信息查询接口
1 ip-api.com
url := "http://ip-api.com/json/"+ip+"?lang=zh-CN"
2 百度
url := "http://opendata.baidu.com/api.php?query="+ip+"&co=&resource_id=6006&oe=utf8"
例如:opendata.baidu.com/api.php?que…
3 太平洋
url := "http://whois.pconline.com.cn/ipJson.jsp?ip="+ip+"&json=true"
例如: whois.pconline.com.cn/ipJson.jsp?…
实战:Go实现查询本地IP & 根据IP查询归属地信息
接下来,将基于Golang
和ip-api.com
的API
,讲解如何实现通过IP获取属地信息
。
- 通过myexternalip.com/raw获取本机的公网ip
- 通过ip-api.com接口查询IP信息
直接看代码吧,除去定义结构体和打印信息,代码也就10行左右
完整代码:
/*
* @Author: starine
* @Date: 2022/5/2 14:04
*/
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"net/http"
)
type IPInfo struct {
Status string `json:"status"`
Country string `json:"country"`
CountryCode string `json:"countryCode"`
Region string `json:"region"`
RegionName string `json:"regionName"`
City string `json:"city"`
Zip string `json:"zip"`
Lat float64 `json:"lat"`
Lon float64 `json:"lon"`
Timezone string `json:"timezone"`
ISP string `json:"isp"`
Org string `json:"org"`
AS string `json:"as"`
QueryIp string `json:"query"`
}
// GetMyPublicIP 通过访问http://myexternalip.com/raw获取公网ip
func GetMyPublicIP() string {
resp, err := http.Get("http://myexternalip.com/raw")
if err != nil {
return ""
}
defer resp.Body.Close()
content, _ := ioutil.ReadAll(resp.Body)
return string(content)
}
// OnlineIpInfo 通过ip-api.com接口查询IP信息
// 返回:IP地址的信息(格式:字符串的json)
func OnlineIpInfo(ip string) *IPInfo {
url := "http://ip-api.com/json/"+ip+"?lang=zh-CN"
resp, err := http.Get(url)
if err != nil {
return nil
}
defer resp.Body.Close()
out, err := ioutil.ReadAll(resp.Body)
if err != nil {
return nil
}
var result IPInfo
if err := json.Unmarshal(out, &result); err != nil {
return nil
}
return &result
}
//测试
func main() {
myIP := GetMyPublicIP()
fmt.Println("本机的公网ip是: ", myIP)
fmt.Println("------查询指定ip的归属地信息------")
result := OnlineIpInfo(myIP)
if result != nil {
fmt.Println("查询的ip是: ", result.QueryIp)
fmt.Println("国家:", result.Country)
fmt.Println("省份:", result.RegionName)
fmt.Println("城市:", result.City)
fmt.Println("纬度:", result.Lat)
fmt.Println("经度:", result.Lon)
fmt.Println("时区:", result.Timezone)
fmt.Println("运营商:", result.ISP)
fmt.Println("AS自治域:", result.AS)
}
}
结果展示:
如何看待这件事?
显示用户IP属地,对于打击网络暴力、恶意造谣、带节奏蹭热度等人们深恶痛绝的网络行为而言,的确迈出了重要一步。长期以来,社交平台的匿名性让部分不怀好意的群体或是发表不实言论、散布有害信息,又或是在热点事件爆发后冒充事发地当事人造谣传谣、带歪舆论节奏,网络空间变得乌烟瘴气,事件真相也因此难以展现在公众面前。在尤其是今年以来,俄乌冲突、上海疫情等热点事件更让不少别有用心的境外网络用户“现出原形”,斩断在网线背后操弄舆论的黑手已变得刻不容缓。从某种程度而言,显示IP属地加强了用户网络行为与现实世界的联结,进一步提升了网络发声的门槛,也让网民在发言时更加慎重。对于以往那些习惯于肆无忌惮辱骂造谣的“键盘侠”而言,这无疑是一种强有力的震慑。
然而要真正杜绝网络不良行为、创造健康有序的网络环境,除不断加强更多技术层面的探索和约束之外,更重要的是规范一个个IP背后人的行为。提高全体网民的网络素养、加大对违法违规网络行为的惩治力度,才能从根本上遏制网络不良之风,让网络空间清朗起来。