视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
php接口怎么保证安全性
2020-11-27 15:21:07 责编:小采
文档
 接口的安全性主要围绕Token、Timestamp和Sign三个机制展开设计,保证接口的数据不会被篡改和重复调用,下面具体来看:

(1)Token授权机制:(Token是客户端访问服务端的凭证)--用户使用用户名密码登录后服务器给客户端返回一个Token(通常是UUID),并将Token-UserId以键值对的形式存放在缓存服务器中。服务端接收到请求后进行Token验证,如果Token不存在,说明请求无效。(推荐学习:PHP编程从入门到精通)

(2)时间戳超时机制:(签名机制保证了数据不会被篡改)用户每次请求都带上当前时间的时间戳timestamp,服务端接收到timestamp后跟当前时间进行比对,如果时间差大于一定时间(比如5分钟),则认为该请求失效。时间戳超时机制是防御DOS攻击的有效手段。

(3)签名机制:将 Token 和 时间戳 加上其他请求参数再用MD5或SHA-1算法(可根据情况加点盐)加密,加密后的数据就是本次请求的签名sign,服务端接收到请求后以同样的算法得到签名,并跟当前的签名进行比对,如果不一样,说明参数被更改过,直接返回错误标识。

/**
 * @desc 接受参数处理
 */
private function dealParam(){
 //接受header参数--系统参数
 $systemParam=getAllHeadersParam();
 //接受body数据--业务参数(json格式)
 $data=file_get_contents('php://input');
 
 //读取配置文件中的私钥信息
 $api_apiKey=C('api_apiKey');
 $privatekey=$api_apiKey[$systemParam['token']];


 $arr['token'] =$systemParam['token']; //服务端分配的标识(不同客户端需使用不同的标识)
 $arr['timestamp']=$systemParam['timestamp']; //时间戳,UTC时间,以北京时间东八区(+8)为准
 $arr['version'] =$systemParam['version']; //版本号
 $arr['sign'] =$systemParam['sign']; //签名
 $arr['source'] =$systemParam['source']; //来源(0-安卓/1-IOS/2-H5/3-PC/4-php/5-java)
 $arr['data'] =json_decode($data,true); //业务参数json格式 
 $arr['method'] =$data['method']; //访问接口,格式:模型名.方法名 

 return $arr;
 }
/*
 * @desc 获取所有以HTTP开头的header参数
 * @return array
 */
private function getAllHeadersParam(){
 $headers = array();
 foreach($_SERVER as $key=>$value){
 if(substr($key, 0, 5)==='HTTP_'){
 $key = substr($key, 5);
 $key = str_replace('_', ' ', $key);
 $key = str_replace(' ', '-', $key);
 $key = strtolower($key);
 $headers[$key] = $value;
 }
 }
 return $headers;
}
/*
 * @desc 签名校验
 * @param $token string 服务端分配的标识(不同客户端需使用不同的标识)
 * @param $timestamp string 时间戳,UTC时间,以北京时间东八区(+8)为准
 * @param $version string 版本号
 * @param $sign string 签名
 * @param $source int 来源(0-安卓/1-IOS/2-H5/3-PC/4-php/5-java)
 * @param $privatekey string 私钥
 * @param $data 业务参数json格式
 * @return bool
 */
private function checkAuth($token,$timestamp,$version,$sign,$source,$privatekey,$data){
 //参数判断
 if(empty($token)){
 E('token不能为空!');
 }
 if(empty($timestamp)){
 E('时间戳不能为空!');
 }
 if(empty($version)){
 E('版本号不能为空!');
 }
 if(empty($data)){
 E('业务参数不能为空!');
 }
 if(empty($source) && $source<>'0'){
 E('来源不能为空!');
 }
 if(empty($sign)){
 E('签名不能为空!');
 }
 if(empty($privatekey)){
 E('私钥不能为空!');
 }
 //时间校验
 $expire_second=C('expire_second',null,10);
 $timestamp_t=$timestamp+$expire_second;
 if($timestamp_t<time()){
 E('请求已经过期!');
 }
 $public= D('public');
 $datas=$this->original;
 //系统参数
 $paramArr=array(
 'token'=>$token,
 'timestamp'=>$timestamp,
 'version'=>$version,
 'source'=>$source,
 'data'=>$data,
 );

 //按规则拼接为字符串
 $str = $this->createSign($paramArr,$this->privatekey);
 
 if($str != $this->sign){
 E('验签错误!');
 }
 return true;
 }

下载本文
显示全文
专题