- A+
所属分类:系统文档
背景需求
在部署网站的时候,有时候需要做个个性一点的,比如谈个小窗,并显示访客IP位置信息。
网上免费的IP位置api少之又少,之前搜狐有个接口,小站也是使用了近两年多,但22年底开始发现异常,他们的接口经常崩溃……于是乎,站长有了自己写api的想法。
想法很美好,现实很残忍。从有想法到最后成品上线,站长也是拖拖拉拉的……庆幸的是最终上线了……
目前接口开放给个人站长免费测试使用:IT小圈IP接口 点击左边链接查看接口文档
设计思路
- 数据库: 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 部分代码
<?php header('Content-Type:application/json; charset=utf-8'); header('Access-Control-Allow-Origin:*'); // 判断请求方式,如果是 GET 直接返回 404 if ( $_SERVER['REQUEST_METHOD'] != 'POST' ){ header('HTTP/1.1 404 Not Found'); header("status: 404 Not Found"); echo "当前页面仅支持 POST 访问"; exit(); } // 接收json数据 $json_input = file_get_contents('php://input'); ?>
-
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 接收注册代码 <?php header('Content-Type:application/json; charset=utf-8'); if ( $_SERVER['REQUEST_METHOD'] != 'POST' ){ header('HTTP/1.1 404 Not Found'); header("status: 404 Not Found"); echo "当前页面仅支持 POST 访问"; exit(); } $json_input = file_get_contents('php://input'); $result_data=exec("bash scripts/useradd.sh '$json_input'"); $result_data = json_decode($result_data,true); echo json_encode($result_data,JSON_UNESCAPED_UNICODE); ?>
-
用户验证
// 主要用于验证注册邮箱的有效性 <?php if ( $_SERVER['REQUEST_METHOD'] != 'GET' ){ header('HTTP/1.1 404 Not Found'); header("status: 404 Not Found"); echo "当前页面仅支持 GET 访问"; exit(); } $ukey = $_GET['ukey']; $dtime = $_GET['dtime']; if ( ! array_key_exists ('ukey',$_GET) || ! array_key_exists ('dtime',$_GET) ){ header('HTTP/1.1 404 Not Found'); header("status: 404 Not Found"); exit(); } $ukey = $_GET['ukey']; $dtime = $_GET['dtime']; $r_data = json_decode(exec("bash scripts/usercheck.sh '$ukey' '$dtime'"),true); echo '<script>alert("'.$r_data['Datatime'].'\n'.$r_data['Msg'].'");</script>'; ?>
-
-
发送邮箱
总结
- 整体来说开发还算顺利
- 其实整个开发也是可以基于php来开发的,只是我比较偏向shell脚本,所以更多就用了shell
- 用户验证之前想过验证码问题,但是后面考虑一下,借鉴目前各大厂在注册时都会发送一个验证邮件的方法,所以验证码也就不用了,这样整体逻辑还比较容易实现
- 代码写多了,现在喜欢写 function 了,在调用的时候真心的方便
- 代码是考虑开源的,但还没有完全测试通过,待测试通过后会公布出来
上述就是我这次的接口开发,不管干啥首先你得清楚你需要啥、你手里有啥,然后再组织逻辑,最后逐一去实现!!
- 我的微信
- 这是我的微信扫一扫
- 我的微信公众号
- 我的微信公众号扫一扫