个人理解:接口简单来讲就是服务器端用来返回给其余程序或者客户端数据的桥梁。算法
1. 防止假装攻击(不知明方调用接口)数组
2. 防止请求篡改(请求的参数被篡改)安全
3. 防止重复攻击(请求被截获,被再次恶意调用)服务器
3. 防止数据泄露(如登录、支付信息)网络
1. 服务端分配客户端特定的调用帐号信息:app
AppID:调用方身份ID,接口提供方用此来识别调不一样的调用者编码
App_secret:用于生成签名sign加密
2. 接口调用方和接口提供方约定好统一的签名加密算法spa
3. 接口调用必要传入参数code
参数名 | 类型 | 必选 | 描述 |
AppId | string | 是 | 调用方身份ID,接口提供方用此来识别调不一样的调用者 |
paramet | mix | 否 | 请求参数 |
timestamp | int | 是 | 时间戳 |
sign | string | 是 | 一次接口调用的签名值,服务器端 “防止 假装请求/防篡改/ 防重发” 识别的重要依据。 |
1. 对除签名外的全部请求参数按key作的升序排列,value无需编码。
(假设当前时间的时间戳是12345678,appid为 testid)
例如:调用接口 www.example.com/v1/user/edit?c=3&b=2&a=1×tamp=12345678
有c=3,b=2,a=1 三个参,另加上时间戳后, 按key排序后为:a=1,b=2,c=3,timestamp=12345678。
2. 把参数名和参数值链接成字符串,获得拼装字符:a1b2c3timestamp12345678
3. 用申请到的appsecret 链接到接拼装字符串头部和尾部,而后进行32位MD5加密,最后将到得MD5加密摘要转化成大写。
示例:假设appkey=test256,strtouppermd5(test256a1b2c3timestamp12345678test256),取得MD5摘要值 C5F3EB5D7DC2748AED89E90AF00081E6 。
此时最终调用: www.example.com/v1/user/edit?c=3&b=2&a=1×tamp=12345678&appid=testid&sign=C5F3EB5D7DC2748AED89E90AF00081E6
1 # 签名的验证方法代码:
2 # $signtype 'yes':验证,'no':不验证
3
4 public function checkSign($args,$signature,$signtype = 'yes')
5 { 6 if($signtype == 'no') //上线时去除该部分,必须验证签名 7 { 8 return true; 9 } 10 if(!$args || !$signature) 11 { 12 return false; 13 } 14 15 //同一签名调用时间限制,能够设定 20s,50s,300s,避免屡次重复调用 16 if (time() - $args['timestamp'] > 300) 17 { 18 return false; 19 } 20 21 //验证 appid 身份合法性,根据appid查询对应的 appsecret 22 $model=Model::where("appid=:appid")->find(); 23 if($model){ 24 $serverSecret=$model->appsecret; 25 }else{ 26 return false; 27 } 28 29 //验证签名 30 ksort($args); //按数组的键排序 31 $sign = ''; 32 33 foreach($args as $k => $v) 34 { 35 $sign .= $k . '=' . $v; 36 } 37 $sign = MD5($serverSecret.$sign.$serverSecret); //加密 38 if($sign == $signature) 39 { 40 return true; 41 } 42 return false; 43 }
总结: