视频点播网站开发,网站建设用的工具,wordpress调用相关评论,产品宣传网页模板前言
有时候为了保护API#xff0c;需要用到 API 签名#xff0c;使用 API 签名的好处#xff1a;
让API只能被特定的人访问防止别人抓包拿到请求参数#xff0c;通过篡改参数发起新的请求
客户端过程
给API调用者分配一个app_id和app_secret#xff0c;app_secret调用…前言
有时候为了保护API需要用到 API 签名使用 API 签名的好处
让API只能被特定的人访问防止别人抓包拿到请求参数通过篡改参数发起新的请求
客户端过程
给API调用者分配一个app_id和app_secretapp_secret调用者和服务端各保存一份不对外泄露app_id需要在调用 API 时作为参数传递。除了app_id参数以外另外增加nonce、timestamp参数。timestamp是时间戳nonce是一个随机字符串每次调用API时都要重新生成且需要保证唯一性。这两个参数主要用来防止重复请求。将参数列表按字典升序排列然后在末尾添加上app_secret参数将参数列表拼接成一个字符串对字符串做md5加密得到signature签名最后将签名也传递给API。 将参数列表拼接成字符串可以有多种实现方法在本文中我们使用这种方案 1将参数列表进行排序按key字典升序排列 2在末尾添加上app_secret参数 3按key1value1key2value2key3value3的格式将参数列表拼接成一个字符串其中value值要经过url编码处理 4拼接完成后做md5运算生成散列值此值便是签名 服务端过程
收到请求后按照app_id参数查询到对应的app_secret判断timestamp参数是否已过期判断nonce参数是否已经被使用剔除sign参数将其它参数按照约定的签名计算方法生成一个签名A将签名A与sign参数进行对比如果一致则通过将nonce参数标记为已使用可以使用redis来存储并设置过期时间 注 1时间戳的超时时间不能设置得太小需要考虑服务端和客户端时间可能会有时差的情况推荐设置为5分钟 2对于nonce参数redis key的过期时间一定要大于时间戳的过期时间比如时间戳过期时间是5分钟那么redis key的过期时间就要 5分钟 PHP代码示例
client.php
?phpfunction genSignature(array $signArr, $appSecret): string
{ksort($signArr, SORT_STRING);$signArr[app_secret] $appSecret;$signStr http_build_query($signArr);return md5($signStr);
}function buildParams(array $params): array
{$appId xxxx;$appSecret yyyy;$params[app_id] $appId;$params[nonce] uniqid(, true);$params[timestamp] time();$params[sign] genSignature($params, $appSecret);return $params;
}$params [username 小明,gender 男,
];
var_dump(buildParams($params));// TODO使用生成的参数调用API接口
server.php
?phpfunction signatureVerify(array $signArr, $appSecret): string
{unset($signArr[sign]);ksort($signArr, SORT_STRING);$signArr[app_secret] $appSecret;$signStr http_build_query($signArr);return md5($signStr);
}$params $_GET;$appId $params[app_id];
// TODO根据app_id参数查找对应的app_secret
$appSecret yyyy;$mySign signatureVerify($params, $appSecret);
if ($mySign $params[sign]) {echo 签名验证成功;
} else {echo 签名验证失败;
}// TODO检查timestamp是否已过期
// TODO检查nonce是否已被使用过
// TODO将nonce存储到redis并设置key的过期时间关于app_secret的安全性
在上述整个过程中最重要的是保证app_secret不外泄如果app_secret外泄了其他人就可以用它来生成签名。
但真实情况下我们很难保证app_secret不外泄如果客户端是server端还好说但如果客户端是浏览器的话由于网页代码都是可以被看到的所以只要查看一遍网页的js代码就可以找到app_secret。
如果客户端是安卓APP别人也可以通过拆解apk安装包破解拿到app_secret。
面对这种情况也没有完美的方法毕竟源代码都被别人看到了还能有啥安全可言。只能通过js代码混淆、apk包安全加固等方法来提高别人找到app_secret的难度。
加密
虽然我们给接口加了签名验证但别人还是可以通过浏览器的开发者工具、或者抓包看到具体传递的参数名和参数值。
如果不想别人看到这些信息的话可以将参数都加密加密方法可以使用RSA加密使用服务端公钥加密服务端收到请求后使用私钥解密、或者AES加密。
加密后别人抓包看到的就都是密文了可以提高别人破解接口的难度。