前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >记一次用Shell开发接口的过程

记一次用Shell开发接口的过程

作者头像
爱技术的小黄鸭
发布2023-06-15 15:15:29
3420
发布2023-06-15 15:15:29
举报
文章被收录于专栏:IT小圈
2023-02-15T15:21:39.png
2023-02-15T15:21:39.png

背景需求

在部署网站的时候,有时候需要做个个性一点的,比如谈个小窗,并显示访客IP位置信息。

2023-02-15T15:55:30.png
2023-02-15T15:55:30.png

网上免费的IP位置api少之又少,之前搜狐有个接口,小站也是使用了近两年多,但22年底开始发现异常,他们的接口经常崩溃……于是乎,站长有了自己写api的想法。

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


设计思路

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

开发测试

请求json

代码语言:javascript
复制
{
"dtime": "2023-01-30 01:15:33",
"ukey": "643b4682ddc002b6aec7d178084bbad79bb5093b5b80246af3d43aacd4a57187",
"ip": "2409:8924:5266:116b:45f:8f2d:a32b:d92c",
"md5": "05f3dc8a944412ff7d5d692d35924548"
}

接口返回json

代码语言:javascript
复制
{
"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 部分代码

代码语言:javascript
复制
<?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 脚本部分代码

代码语言:javascript
复制
// 主脚本 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/}"
}

用户管理部分

用户注册

代码语言:javascript
复制
// 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);
?>

用户验证

代码语言:javascript
复制
// 主要用于验证注册邮箱的有效性
<?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>';
?>

发送邮箱

  • 邮箱发送考虑到格式问题,这里主要用到 PHPMailer
2023-02-15T16:00:57.png
2023-02-15T16:00:57.png
2023-02-15T16:01:43.png
2023-02-15T16:01:43.png

总结

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

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

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-02-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景需求
  • 设计思路
  • 开发测试
  • 总结
相关产品与服务
验证码
腾讯云新一代行为验证码(Captcha),基于十道安全栅栏, 为网页、App、小程序开发者打造立体、全面的人机验证。最大程度保护注册登录、活动秒杀、点赞发帖、数据保护等各大场景下业务安全的同时,提供更精细化的用户体验。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档