API接口安全加强设计方法
前面两篇相关文章:
《Web Api 内部数据思考 和 利用http缓存优化 Api》
1.开放的接口
这样的接口我们天天都在接触,例如查快递,你查天气预报,你查飞机,火车班次等,这些都是有公共的接口。
例如腾讯的开放平台:
<?php /**
* OpenAPI V3 SDK 示例代码,适用于大部分OpenAPI。如果是上传文件类OpenAPI,请参考本SDK包中的“Test_UploadFile.php”文件中的示例代码。
*
* @version 3.0.4
* @author open.qq.com
* @copyright © 2012, Tencent Corporation. All rights reserved.
* @History:
* 3.0.4 | coolinchen | 2012-09-07 10:20:12 | initialization
*/ require_once 'OpenApiV3.php'; // 应用基本信息
$appid = ;
$appkey = 'b96b85196a04ff2ef08707f43979db15'; // OpenAPI的服务器IP
// 最新的API服务器地址请参考wiki文档: http://wiki.open.qq.com/wiki/API3.0%E6%96%87%E6%A1%A3
$server_name = '119.147.19.43'; // 用户的OpenID/OpenKey
$openid = 'E098C1E975A2459E534B48FB3224CFB6';
$openkey = '05219DB6D7C04CA0B3F01A51D32635E3'; // 所要访问的平台, pf的其他取值参考wiki文档: http://wiki.open.qq.com/wiki/API3.0%E6%96%87%E6%A1%A3
$pf = 'qzone'; $sdk = new OpenApiV3($appid, $appkey);
$sdk->setServerName($server_name); $ret = get_user_info($sdk, $openid, $openkey, $pf);
print_r("===========================\n");
print_r($ret); /**
* 获取好友资料
*
* @param object $sdk OpenApiV3 Object
* @param string $openid openid
* @param string $openkey openkey
* @param string $pf 平台
* @return array 好友资料数组
*/
function get_user_info($sdk, $openid, $openkey, $pf)
{
$params = array(
'openid' => $openid,
'openkey' => $openkey,
'pf' => $pf,
); $script_name = '/v3/user/get_info';
return $sdk->api($script_name, $params,'post');
}
2.接口参数加密(基础加密)
验证彼此约定好的key,验证通过,即可调用api。
/**
* 签名验证
*
* @version 2017-08-14
*/
function checkSign( $dataAry )
{
if(GAME_KEY == $dataAry['sign']) { //GAME_KEY为 项目中的key , sign 为传递过来的签名,简单的验证是否对等,便通过
return true;
} return false;
} //验证签名 不通过直接返回
if(!checkSign($paramsAry)) {
$retCode = ;
echo makeReturn($paramsAry,$retCode);
exit();
}
这样子做的缺点如下:
1 如果不小心把key泄露,那么很容易被他人调用接口
2 开发者经常把sign附带于URL中进行请求,这样子容易被获取到URL请求参数,进而拿到sign
加强方法:
1 把URL请求参数进行base64为加密后再请求,或其他加密方式,将请求参数进行加密后,再请求
2 限制可请求接口的ip 【一般用于充值等高防范的接口中】
3.变换的接口参数加密【较为安全】
key 不会永远都是安全的,也有可能被泄露,那么我们可以怎么做呢?我们可以生成变换的签名sign,且辅助其他参数进行排序变化加密
例如对所有的参数(加上时间戳),按照首字母进行排序后,进行md5或sha加密,这时候每次生成的sign都是变化的,其他人即使拿到了key,如果不知道排序方式与加密方式,那么是无法算出sign的。
例如:
/**
* 生成签名
*
* @param $params 参数列表 数组 array('param1'=>'value1','param2'=>'value3',...)
* @param $key 密钥 默认从配置文件取(GAME_KEY)
*/
function genSign($params,$key='')
{
if($key == '') {
$key = GAME_KEY;
}
//过滤空值
$paraFilter = array();
while (list ($k, $v) = each ($params)) {
if($k == 'sign' || $v == '')continue;
else $paraFilter[$k] = $params[$k];
} //升序排列数
ksort($paraFilter);
reset($paraFilter); //生成参数字符串
$paramsString = "";
while (list ($k, $v) = each ($paraFilter)) {
$paramsString.=$k."=".$v."&";
}
//去掉最后一个&字符
$paramsString = substr($paramsString,,count($paramsString)-);
//如果存在转义字符,那么去掉转义
if(get_magic_quotes_gpc()){$paramsString = stripslashes($paramsString);} //加上key,进行md5
$paramsString .='&key='.$key;
$sign = md5($paramsString); return $sign;
}
可加强点:
1 尾部带上双方约定好的key,再进行md5与sha同时加密
2 url参数同时也要进行base64或者其他加密,例如最后能看到的请求url为:
http://www.example.com/pay.php?data = SDDLKFKDKFLDHOIDHSALFSALDJALDSSALKJLDJSALDMSA
3 不要明显的提示缺少什么参数,而且准确的使用错误码。
4 . 变换的接口参数加密 + ip验证【非必须】 + 时效性检查 + https 【安全性高】
只有特定的ip,才允许请求这个接口:
/**
* 获取客户端IP地址
*
*/
function getIp()
{
$realip='';
if (isset($_SERVER)){
if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])){
$realip = $_SERVER["HTTP_X_FORWARDED_FOR"];
} else if (isset($_SERVER["HTTP_CLIENT_IP"])) {
$realip = $_SERVER["HTTP_CLIENT_IP"];
} else {
$realip = $_SERVER["REMOTE_ADDR"];
}
} else {
if (getenv("HTTP_X_FORWARDED_FOR")){
$realip = getenv("HTTP_X_FORWARDED_FOR");
} else if (getenv("HTTP_CLIENT_IP")) {
$realip = getenv("HTTP_CLIENT_IP");
} else {
$realip = getenv("REMOTE_ADDR");
}
} return $realip;
} if(getIp() != '特定的ip'){
echo makeReturn($paramsAry,$retCode);
exit();
}
进行时效性检查:
/**
* 检查是否url过期
* @param int $ts 时间戳
* @param int $limitTime 有效期:默认为5分钟
* @return string or boolean 成功且对方有返回值则返回
*/
function checkTime($ts, $limitTime='') // 5分钟的有效期
{
$sencond = abs(time()-$ts);
if ($sencond<=$limitTime)
{
return true;
}
return false;
}
HTTPS这块相对比较麻烦,我们项目所用的是免费版本的,所以经常弹出验证框。后面终于买了个收费版本,用起来挺好。
4 . 总结
在安全的同时,要根据业务进行接口的调整,例如:
1 API版本的迭代规范,版本分支(例手游项目接口迭代比较重要),开发规范,模块管理(例如页游对接平台较多,模块管理比较重要)。
2 客户端与服务端的双向验证,很多时候大部分都是服务端验证,然后返回错误码,客户端进行错误码验证是否正确,某些情况下,我们也可以服务端验证通过后,客户端同时也进行验证服务端返回的内容。
3 可以在限定ip下,请求唯一入口api来获取其他接口的key,这也是一个不错的办法。key可以随便改变且不用通知接入方。
API接口安全加强设计方法的更多相关文章
- Api接口幂等设计
1,Api接口幂等设计,也就是要保证数据的唯一性,不允许有重复. 例如:rpc 远程调用,因为网络延迟,出现了调用了2次的情况. 表单连续点击,出现了重复提交. 接口暴露之后,会被模拟请求工具(Jem ...
- API接口幂等性框架设计
表单重复提价问题 rpc远程调用时候 发生网络延迟 可能有重试机制 MQ消费者幂等(保证唯一)一样 解决方案: token 令牌 保证唯一的并且是临时的 过一段时间失效 分布式: redis+to ...
- 创建包含CRUD操作的Web API接口2:实现Get方法
本节是前一节的延续,上一节中我们已经为我们的Web API项目创建必要的基础设施. 在本节中,我们将在我们的控制器类中实现操作方法,这些方法用来处理HTTP GET请求. 根据Web API命名约定, ...
- Api接口服务的设计和安全解决方案
这个涉及到两个方面问题:一个是接口访问认证问题,主要解决谁可以使用接口(用户登录验证.来路验证)一个是数据数据传输安全,主要解决接口数据被监听(HTTPS安全传输.敏感内容加密.数字签名) 普通网站应 ...
- 微信小程序的Web API接口设计及常见接口实现
微信小程序给我们提供了一个很好的开发平台,可以用于展现各种数据和实现丰富的功能,通过小程序的请求Web API 平台获取JSON数据后,可以在小程序界面上进行数据的动态展示.在数据的关键 一环中,我们 ...
- 防盗链&CSRF&API接口幂等性设计
防盗链技术 CSRF(模拟请求) 分析防止伪造Token请求攻击 互联网API接口幂等性设计 忘记密码漏洞分析 1.Http请求防盗链 什么是防盗链 比如A网站有一张图片,被B网站直接通过img标签属 ...
- 不使用jQuery对Web API接口POST,PUT,DELETE数据
前些天,Insus.NET有演示Web API接口的操作: <怎样操作WebAPI接口(显示数据)>http://www.cnblogs.com/insus/p/5670401.html ...
- 微服务手册:API接口9个生命节点,构建全生命周期管理
互联网应用架构:专注编程教学,架构,JAVA,Python,微服务,机器学习等领域,欢迎关注,一起学习. 对于API,在日常的工作中是接触最多的东西,特别是我们软件这一行,基本就是家常便饭了,在百度百 ...
- Python多线程豆瓣影评API接口爬虫
爬虫库 使用简单的requests库,这是一个阻塞的库,速度比较慢. 解析使用XPATH表达式 总体采用类的形式 多线程 使用concurrent.future并发模块,建立线程池,把future对象 ...
随机推荐
- JS: 如何计算一个月有多少天
转自:https://www.2cto.com/kf/201806/755776.html 1 function getCountDays() { var curDate = new Date(); ...
- UGUI 锚点设置为四方扩充模式然后设置局部坐标为0将出现什么问题
UGUI 锚点设置为四方扩充模式然后设置局部坐标为0将出现什么问题? 情形:按钮A挂在主画布上.四方扩充模式.A的中心和画面中心不重合. 这时候用代码设置A.localPosition = new V ...
- sqlserver job 执行时间
select instance_id,jh.run_date,jh.job_id,jh.step_name, case jh.run_status then 'failed' then 'Succee ...
- Python next() 函数
Python next() 函数 Python 内置函数 描述 next() 返回迭代器的下一个项目. 语法 next 语法: next(iterator[, default]) 参数说明: ite ...
- 44. Wildcard Matching (String; DP, Back-Track)
Implement wildcard pattern matching with support for '?' and '*'. '?' Matches any single character. ...
- 图是否是树 · Graph Valid Tree
[抄题]: 给出 n 个节点,标号分别从 0 到 n - 1 并且给出一个 无向边的列表 (给出每条边的两个顶点), 写一个函数去判断这张`无向`图是否是一棵树. 给出n = 5 并且 edges = ...
- 8-matlab-gui-显示图片有坐标刻度问题
在图片上显示图片时,总是有图片,一遍做法是使得刻度为空就可了: 在你的每一个axes的CreateFcn函数中添加一下代码即可:set(hObject,'xTick',[]);set(hObject, ...
- DSOFramer 控件修改成功
1.Html电子印章.手写签名系统演示:http://www.dianju.com.cn/video.htm 在线试用: http://www.dianju.com.cn/websignpiaoju/ ...
- Android Service 通知Activity更新界面的方法研究
Android Service 通知Activity更新界面的方法研究 Android的最重要的组件式service和activity,那么在使用的过程中,我们最常遇到的问题是他们之间的通信问题. ...
- 看图说说JVM新生代垃圾收集器