![2023-02-15T15:21:39.png][1]

背景需求

在部署网站的时候,有时候需要做个个性一点的,比如谈个小窗,并显示访客IP位置信息。 ![2023-02-15T15:55:30.png][2] 网上免费的IP位置api少之又少,之前搜狐有个接口,小站也是使用了近两年多,但22年底开始发现异常,他们的接口经常崩溃……于是乎,站长有了自己写api的想法。

想法很美好,现实很残忍。从有想法到最后成品上线,站长也是拖拖拉拉的……庆幸的是最终上线了…… 目前接口开放给个人站长免费测试使用:[IT小圈IP接口][3] 点击左边链接查看接口文档


设计思路

  • 数据库: mariadb
  • 接收脚本:php
  • 接收方式:post
  • 后台逻辑脚本:Shell
  • 系统平台:Linux ,需要 jq 工具
  • 站长注册使用接口,需要验证邮箱的有效性和网址的所有权

开发测试

  • 请求json
{
  "dtime": "2023-01-30 01:15:33",
  "ukey": "643b4682ddc002b6aec7d178084bbad79bb5093b5b80246af3d43aacd4a57187",
  "ip": "2409:8924:5266:116b:45f:8f2d:a32b:d92c",
  "md5": "05f3dc8a944412ff7d5d692d35924548"
}
  • 接口返回json
{
"Code": "Good",
"iptype": "IPv6",
"ip": "2409:8924:5266:116b:45f:8f2d:a32b:d92c",
"isp": "中国移动无线基站网络",
"ip_location": "中国江苏省苏州市常熟市",
"data_src": "IT小圈API",
"jzstr": "蓦然回首,几个春秋;凉风依旧,岁月不休",
"Datatime": "2023-02-08 02:33:17"
}
  • getip.php 部分代码

  • Shell 脚本部分代码
// 主脚本 main_chec.sh  由 getip.php直接调用
#!/bin/bash

. scripts/public.sh
. scripts/ip_check.sh

json_data="${1}"
ukey=$(echo ${json_data} | jq -r .ukey | tr -d ' ')
cip=$(echo ${json_data} | jq -r .ip | tr -d ' ')
dtime=$(echo ${json_data} | jq -r .dtime)
md5=$(echo ${json_data} | jq -r .md5 | tr -d ' ')
logs_time=$(date "+%F %H:%M:%S")

## echo ${json_data} > json.txt
if [ $(echo -n "${json_data}" | jq ". | length") -ne 4 ];then
  sendMsg 1 "Json 消息体长度不符"
fi
if [[ ! -n "${dtime}" ]] && [[ ! -n "${ukey}" ]] && [[ ! -n "${cip}" ]] && [[ ! -n "${md5}" ]];then
  sendMsg 1 "Json 主体 'ukey,ip,dtime,md5' 值不能为空"
fi

## Time check
if [ $(( $(date -d "${dtime}" "+%s") + 60 )) -lt $(date "+%s") ];then
  sendMsg 1 "请求超时或时间系统错误"
fi

## user check
userinfo=$(sql "select CONCAT('[',GROUP_CONCAT(JSON_OBJECT('ukey',ukey,'utype',utype,'endtime',endtime,'uenable',uenable,'daymax',daymax,'daycount',daycount)),']') as reluast from ${db_name}.ipuser where  ukey='${ukey}'" | grep ']')
echo "${userinfo}" | grep -q -w "${ukey}"
if [ $? -ne 0 ] ;then
  sendMsg 1 "用户key ${ukey} 错误或不存在,请检查或注册"
fi

if [ $(echo "${userinfo}" | jq -r .[0].uenable) -ne 1 ];then
  sendMsg 1 "用户key ${ukey} 已被禁用,请联系管理员开通"
fi

if [ $(echo "${userinfo}" | jq -r .[0].daymax) -lt $(echo "${userinfo}" | jq -r .[0].daycount) ];then
  sendMsg 1 "用户key ${ukey} 日请求量已超,请明日再尝试"
fi
endtime=$(echo "${userinfo}" | jq -r .[0].endtime)
if [ $(date -d "${endtime}" "+%s") -lt $(date "+%s") ];then
  sendMsg 1 "用户key ${ukey} 已过有效期,请联系管理员处理"
fi
if [ $(echo "${userinfo}" | jq -r .[0].daymax) -ne 999 ];then
  daycount=$(echo "${userinfo}" | jq -r .[0].daycount)
  n=$(( ${daycount} + 1 ))
  sql "update ${db_name}.ipuser set daycount='${n}' where ukey='${ukey}'"
fi

// ip 查询脚本 ip_check.sh  由 main_chec.sh 调用
#!/bin/bash

function returnMsg(){
  echo -n "{\"Code\":\"Good\",${1},\"jzstr\":\"${jzstr}\",\"Datatime\":\"$(date '+%F %H:%M:%S')\"}"
}

function isp_v4(){
  if echo "${isp}" | grep -q '电信';then
    isp='中国电信'
  elif echo "${isp}" | grep -q '联通';then
    isp='中国联通'
  elif echo "${isp}" | grep -q '移动';then
    isp='中国移动'
  elif  echo "${isp}" | grep -q '阿里巴巴';then
    isp='阿里数据中心'
  elif  echo "${isp}" | grep -q 'tencent';then
    isp='腾讯数据中心'
  else
    isp='未知运营商'
  fi

}
function ip4(){
  if [ $( echo -n ${1} | grep -E '^192.168') ];then
    str=$(returnMsg "\"iptype\":\"IPv4\",\"ip\":\"${cip}\",\"infocode\":\"局域网IP\",\"ip_location\":\"局域网IP\",\"lat\":\"局域网IP\",\"data_src\":\"局域网API\"")
  else
    ipint=$(php scripts/ip.php 1 "${cip}")
    ip_str=$(sql "select CONCAT('[',GROUP_CONCAT(JSON_OBJECT('ip',ipv4,'lat',lat,'lo',local,'isp',isp)),']') as reluast from ${db_name}.ipv4 where ipv4='${ipint}'" | grep ']')
    if echo "${ip_str}" | grep -q -w "${ipint}";then
      lat=$(echo ${ip_str} | jq -r .[0].lat)
      lo=$(echo ${ip_str} | jq -r .[0].lo)
      isp=$(echo ${ip_str} | jq -r .[0].isp)
      str=$(returnMsg "\"iptype\":\"IPv4\",\"ip\":\"${cip}\",\"isp\":\"${isp}\",\"ip_location\":\"${lo}\",\"lat\":\"${lat}\",\"data_src\":\"IT小圈API\"")
    else
      ip_data=$(curl -s "${gmap_url}${cip}&key=${gmap_key}")
      location=$(echo ${ip_data} | jq -r '.country,.province,.city,.district' | tr -d '\n')
      lat=$(echo ${ip_data} | jq -r '.location')
      isp=$(echo ${ip_data} | jq -r '.isp')
      isp_v4
      str=$(returnMsg "\"iptype\":\"IPv4\",\"ip\":\"${cip}\",\"isp\":\"${isp}\",\"ip_location\":\"$location\",\"lat\":\"${lat}\",\"data_src\":\"高德API\"")
      intime=$(date "+%F %H:%M:%S")
      if echo ${location} | grep -q '中国';then
        sql "insert into ${db_name}.ipv4 values('${intime}','${ipint}','${lat}','${location}','${isp}');"
      fi
    fi
  fi
  ip_json="${str//null/}"
}

function ip6_isp(){
  lo_6=$(echo -n "${lo}" | awk '{print $1}')
  isp_6=$(echo -n "${lo}" | awk '{print $2}')
}
function ip6(){
  ip6_str=$(sql "select CONCAT('[',GROUP_CONCAT(JSON_OBJECT('ip',ipv6,'lo',local,'isp',isp)),']') as reluast from ${db_name}.ipv6 where ipv6='${cip}'" | grep ']')
  if echo "${ip6_str}" | grep -q -w "${cip}";then
    lo_6=$(echo "${ip6_str}" | jq -r .[0].lo)
    # ip6_isp
    isp_6=$(echo "${ip6_str}" | jq -r .[0].isp)
    str=$(returnMsg "\"iptype\":\"IPv6\",\"ip\":\"${cip}\",\"isp\":\"${isp_6}\",\"ip_location\":\"${lo_6}\",\"data_src\":\"IT小圈API\"")
  else
    url="${ipv6_url}${cip}"
    lo=$(curl -s ${url} | tr -d '\\t' | jq -r .daa.locaion)
    ip6_isp
    str=$(returnMsg "\"iptype\":\"IPv6\",\"ip\":\"${cip}\",\"isp\":\"${isp_6}\",\"ip_location\":\"${lo_6}\",\"data_src\":\"IPv6临时API\"")
    intime=$(date "+%F %H:%M:%S")
    if echo ${lo} | grep -q '中国';then
      sql "insert into ${db_name}.ipv6 values('${intime}','${cip}','${lo_6}','${isp_6}');"
    fi
  fi
  ip_json="${str//null/}"
}

  • 用户管理部分
    • 用户注册
    // php 接收注册代码
    

?>

- 用户验证

// 主要用于验证注册邮箱的有效性

alert("'.$r_data['Datatime'].'\n'.$r_data['Msg'].'");'; ?>
- 发送邮箱
- 邮箱发送考虑到格式问题,这里主要用到 `PHPMailer` 库
![2023-02-15T16:00:57.png][4]
![2023-02-15T16:01:43.png][5]

# 总结
- 整体来说开发还算顺利
- 其实整个开发也是可以基于php来开发的,只是我比较偏向shell脚本,所以更多就用了shell
- 用户验证之前想过验证码问题,但是后面考虑一下,借鉴目前各大厂在注册时都会发送一个验证邮件的方法,所以验证码也就不用了,这样整体逻辑还比较容易实现
- 代码写多了,现在喜欢写 function 了,在调用的时候真心的方便
- 代码是考虑开源的,但还没有完全测试通过,待测试通过后会公布出来

上述就是我这次的接口开发,不管干啥首先你得清楚你需要啥、你手里有啥,然后再组织逻辑,最后逐一去实现!!


[1]: https://deyun.fun/usr/uploads/2023/02/2081312521.png
[2]: https://deyun.fun/usr/uploads/2023/02/1968527796.png
[3]: https://ip.iquan.fun
[4]: https://deyun.fun/usr/uploads/2023/02/2129763641.png
[5]: https://deyun.fun/usr/uploads/2023/02/470606009.png

「 希望熬过一切,星光璀璨 」

流年小站,感谢有您的支持

「 道路坎坷,感谢有您 ---来自 anYun 的感谢 」

使用微信扫描二维码完成支付

2023-02-15
已阅:7527 人/次

 
 
 
分享是一种美德 x
打开微信,右上角的"+"选择"扫一扫"
使用“扫一扫”将博文分享至朋友圈吧

本文由 anYun 创作,采用 知识共享署名 3.0,可自由转载、引用,但需署名作者且注明文章出处。
我的博客即将同步至腾讯云开发者社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite_code=3oibnoh9lo6cs

还不快抢沙发

添加新评论

Myssl安全认证