PHP接口签名校验
短信预约 -IT技能 免费直播动态提醒
项目中常用的API接口签名验证方法:
给app分配对应的appId、appKey
2. Sign签名,调用API 时需要对请求参数进行签名验证,签名方式如下:
a. 按照请求参数名称将所有请求参数按照键名进行升序排序,如:将arong=1,mrong=2,crong=3 排序为:arong=1, crong=3,mrong=2 然后将参数名和参数值进行拼接得到参数字符串:arong=1&crong=3&mrong=2
b. 将appKey加在参数字符串的尾部&key=appKey后进行MD5加密 ,加密后的字符串需转小写。即得到签名Sign;
php签名类
namespace utils;class Sign{ private $appId = "2jOlqkesGGeJJwMx"; private $appKey = "wfEj1kXLdKjCV6rla6Rfasd"; //创建sign public function makeSign($data) { ksort($data); $string = $this->toUrlParams($data); $string = $string . "&key=" . $this->appKey; $string = md5($string); $result = strtolower($string); return $result; } //检验sign是否正确 public function verifySign($data) { //check sign if (!isset($data['sign']) || !$data['sign']) { return ['code' => 1, 'msg' => '发送的数据签名sign不存在']; } //check sign if (!isset($data['appid']) || !$data['appid']) { return ['code' => 1, 'msg' => '发送的应用参数appid不存在']; } if ($data['appid'] != $this->appId) { return ['code' => 1, 'msg' => '发送的应用参数appid错误']; } //check sign if (!isset($data['nonce']) || !$data['nonce']) { return ['code' => 1, 'msg' => '发送的应用参数nonce不存在']; } //check timestamp if (!isset($data['timestamp']) || !$data['timestamp']) { return ['code' => 1, 'msg' => '发送的数据参数timestamp不合法']; } // 验证请求, 10分钟失效 if (time() - $data['timestamp'] > 600) { return ['code' => 1, 'msg' => '验证超时timestamp请重新发送请求']; } $clientSign = $data['sign']; unset($data['sign']); $serverSign = $this->makeSign($data); if ($clientSign == $serverSign) { return ['code' => 0, 'msg' => '验证通过']; } else { return ['code' => 1, 'msg' => '签名校验失败']; } } //生成url字符串 private function toUrlParams($values) { $buff = ""; foreach ($values as $k => $v) { if ($k != "sign" && !is_array($v)) { $buff .= $k . "=" . $v . "&"; } } $buff = trim($buff, "&"); return $buff; }}
使用实例,签名校验可以写在中间件拦截
namespace app\api\controller;use think\facade\Request;use utils\Sign;class Test{ public function sign(Request $request) { //接口签名校验 $appid = $request->header('appid', ''); $nonce = $request->header('nonce', ''); $timestamp = $request->header('timestamp', ''); $sign = $request->header('sign', ''); $Sign = app(Sign::class); $verifySign = $Sign->verifySign(compact('appid', 'nonce', 'timestamp', 'sign')); if (isset($verifySign['code']) && $verifySign['code']) { throw new IllegalException(); } }}
前端vue代码
<div id="app"></div><script class="lazy" data-src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script><script class="lazy" data-src="https://unpkg.com/axios/dist/axios.min.js"></script><script class="lazy" data-src="https://cdn.bootcss.com/blueimp-md5/2.10.0/js/md5.min.js"></script><script type="text/javascript"> new Vue({ el: '#app', data() { return { info: null } }, create(){ }, methods: { getSign: function(param,key) { let str = ""; for(var idx in param) { let one = idx+"="+param[idx]; if (str == "") { str = one; } else { str = str+"&"+one; } } str = str+"&key="+key; //console.log("before md5:"+str); let md5str = md5(str); return md5str; } }, mounted() { let appid = "2jOlqkesGGeJJwMx"; let appkey = "wfEj1kXLdKjCV6rla6Rfasd"; let timestamp = parseInt((new Date()).getTime()/1000); let nonce = Math.floor(Math.random()*8999)+1000; let param = { appid:appid, nonce:nonce, timestamp:timestamp, } let sign = this.getSign(param,appkey); param.sign = sign; console.log(param); const config = { headers: { appid: param.appid, nonce: param.nonce, timestamp: param.timestamp, sign:param.sign, } }; axios .post('https://www.baidu.com/api/Test/sign',[],config) .then(response => (this.info = response)) .catch(function (error) { // 请求失败处理 console.log(error); }); } })</script>
来源地址:https://blog.csdn.net/qqq13500169/article/details/128573157
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341