From 6804ad03c03df5b46570fac319e107a425c63b3d Mon Sep 17 00:00:00 2001 From: xiaoqidun Date: Fri, 1 Oct 2021 12:44:02 +0800 Subject: [PATCH] =?UTF-8?q?feat(=E5=AE=9E=E7=8E=B0=E5=8A=9F=E8=83=BD):=20?= =?UTF-8?q?=E4=BD=BF=E7=94=A8=E9=AB=98=E5=BE=B7IP=E5=AE=9A=E4=BD=8D2.0?= =?UTF-8?q?=E5=AE=9E=E7=8E=B0=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 14 +++++++++ aipdw.go | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++ aipdw_util.go | 42 +++++++++++++++++++++++++ 3 files changed, 141 insertions(+) create mode 100644 aipdw.go create mode 100644 aipdw_util.go diff --git a/README.md b/README.md index ebc03e1..0b871a8 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,16 @@ # aipdw + Golang 高德IP定位库 + +# 在线演示 + +- [https://aite.xyz/aipdw](https://aite.xyz/aipdw) + +# 类似项目 + +- [https://github.com/xiaoqidun/tipdw](https://github.com/xiaoqidun/tipdw) + +# 接口文档 + +- [https://lbs.amap.com/faq/quota-key/key/41181](https://lbs.amap.com/faq/quota-key/key/41181) +- [https://lbs.amap.com/api/webservice/guide/api/ipconfig](https://lbs.amap.com/api/webservice/guide/api/ipconfig) \ No newline at end of file diff --git a/aipdw.go b/aipdw.go new file mode 100644 index 0000000..649cf56 --- /dev/null +++ b/aipdw.go @@ -0,0 +1,85 @@ +package aipdw + +import ( + "encoding/json" + "errors" + "fmt" + "io/ioutil" + "net" + "net/http" + "sync" + "time" +) + +var ( + client = &http.Client{Timeout: 5 * time.Second} + ipCache = &sync.Map{} +) + +type Body struct { + Status string `json:"status"` // 返回结果状态值,值为0或1,0表示失败;1表示成功 + Info string `json:"info"` // status为0时,info返回错误原因;否则返回“OK” + Infocode string `json:"infocode"` // 返回状态说明,10000代表正确,详情参阅info状态表 + Result +} + +type Result struct { + Country string `json:"country"` // 国家 + Province string `json:"province"` // 省份 + City string `json:"city"` // 城市 + District string `json:"district"` // 区县 + Isp string `json:"isp"` // 运营商 + Location string `json:"location"` // 经纬度 + IP string `json:"ip"` // IP地址 +} + +// QueryIP 使用高德位置服务查询IP +func QueryIP(sk string, key string, ip string) (result Result, err error) { + v, ok := ipCache.Load(ip) + if ok { + result = v.(Result) + return + } + pip := net.ParseIP(ip) + if pip == nil { + err = errors.New("ip is not ipv4 or ipv6") + return + } + ipt := "6" + if pip.To4() != nil { + ipt = "4" + } + arg := &reqLBS{ + SK: sk, + Args: map[string]string{ + "ip": ip, + "key": key, + "type": ipt, + }, + } + req, err := http.NewRequest(http.MethodGet, fmt.Sprintf("%s?%s", "https://restapi.amap.com/v5/ip", arg.Encode()), nil) + if err != nil { + return + } + resp, err := client.Do(req) + if err != nil { + return + } + defer resp.Body.Close() + body, err := ioutil.ReadAll(resp.Body) + if err != nil { + return + } + var bodyUnmarshal Body + err = json.Unmarshal(body, &bodyUnmarshal) + if err != nil { + return + } + if bodyUnmarshal.Infocode != "10000" { + err = fmt.Errorf("resp code is %s, body is %s", bodyUnmarshal.Infocode, body) + return + } + result = bodyUnmarshal.Result + ipCache.Store(ip, bodyUnmarshal.Result) + return +} diff --git a/aipdw_util.go b/aipdw_util.go new file mode 100644 index 0000000..7782e1f --- /dev/null +++ b/aipdw_util.go @@ -0,0 +1,42 @@ +package aipdw + +import ( + "crypto/md5" + "encoding/hex" + "fmt" + "net/url" + "sort" + "strings" +) + +type reqLBS struct { + SK string + Args map[string]string +} + +func (r *reqLBS) Encode() string { + r.Signature() + req := url.Values{} + for k, v := range r.Args { + req.Set(k, v) + } + return req.Encode() +} + +func (r *reqLBS) Signature() { + if r.Args == nil { + r.Args = make(map[string]string) + } + var keys []string + for k := range r.Args { + keys = append(keys, k) + } + sort.Strings(keys) + var keyValue []string + for i := 0; i < len(keys); i++ { + keyValue = append(keyValue, fmt.Sprintf("%s=%s", keys[i], r.Args[keys[i]])) + } + signStr := strings.Join(keyValue, "&") + r.SK + signMd5 := md5.Sum([]byte(signStr)) + r.Args["sig"] = hex.EncodeToString(signMd5[:]) +}