在设计API时,对安全性有要求的情况下经常需要要求校验参数,或者需要防止代码入侵,需要对接口中的参数进行验证,这里提供一种简单的方法。
这里使用世界上最好的语言(斜眼笑)来举例
这里假设有一个接口:https://xxx.com/u/Token
完整请求为http://xxx.com/u/Token?ID=111&UserPhone=15099999999&Sign=a4a2a2ad411c81a403e586619182e080
其中ID
和UserPhone
为有价值参数,注意到这里有个Sign
参数,这就是我们这个方式的核心,我们可以通过对传输的所有参数按照传输顺序组成字符串再添加一个约定加密key
组成一个字符串再进行md5
或者sha1
之类的不可逆加密生成一个Sign
字符串添加到最后。每次进行请求处理之前都先检验生成的Sign
与参数中的Sign
是否一致,若不一致则拒绝请求。
这里通过上面的请求举例,先获取请求参数
$params = $_REQUEST;
//php中这里获得的一个参数组成的数。$params = ['ID'=>111,'UserPhone'=>15099999999,'Sign'=>'a4a2a2ad411c81a403e586619182e080'];
注意这里参数包含了Sign
我们首先需要去除这个参数
unset($params['Sign']);
//PHP中这个方法会删除数组$params中'key'为的'Sign'的元素项;
这个时候就是我们所有的有效参数组成的数组了,我们在这里添加一个加密用的key
,我们在此约定一个加密key
为thisisoursecret
,
$params['key'] = 'thisisoursecret';
然后将其转为URL参数字符串
$responseParams = http_build_query($params);
//PHP中可以获得'ID=111&UserPhone=15099999999&key=thisisoursecret',如果别的语言没有类似的方法也可以自己写一个。
获得添加key的url参数字符串的过程也可以一开始直接获取完整GET参数字符串然后使用正则去除
Sign
后使用字符串连接的方法把key
添加的方式。
再使用md5
加密
md5($responseParams);
即可得到最后的Sign
字符串。
下面是已经封装成函数的代码
/**
* 获取Token
*/
public function Token()
{
$data = $_REQUEST;
$responseParams = '';
if (self::HBBCreateSign($data) == $data['Sign']) {
$responseParams = array(
'RetCode' => '1',
'RetMsg' => '成功',
'TokenID' => $tokenKey,
);
$responseParams['Sign'] = self::creteaSign($responseParams);
} else {
$responseParams = array(
'RetCode' => '0',
'RetMsg' => '验签失败',
);
}
echo json_encode($responseParams);
}
/**
* 创建一个Sign字符串
* @param {Array} 可能包含Sign的参数数组
*/
private function creteaSign($params)
{
if(isset($params['Sign']) unset($params['Sign']);
$params['key'] = 'thisisoursecret';
return md5(http_build_query($params));
}