关于平台接入:签名验证

时间:2022-10-13 20:20:41

前段时间独立做了几个平台的接入,譬如生活信息分类平台的订单接入、百度应用内搜索的社区内容接入。这里总结一下平台接入的相关事宜。

签名验证

签名验证是接入平台需要最先完成的工作。哪怕是自己系统的接口请求,或者是自己公司移动端的App请求网站接口也需要做好签名验证,防止跨域的攻击或者网络爬虫对系统造成意想不到的问题。

1. 最偷懒的办法

最简单的签名验证就是在请求的URL里加上一段特定的字符串。譬如你的接口地址在http://yourhost/index.php?controller=apilist&action=oneApi,你可以在URL末尾加上一个参数,比如说key=meiyouqianming,然后在你的代码里验证一下是否存在参数key,其值是不是meiyouqianming(没有签名)就好了。简直偷懒到家。

2. 利用sha1、md5之类的算法生成签名

另外有将平台提供的secret_key与请求参数做hash_hmac运算生成一个签名字符串,然后一起传到服务器上。目标服务器重新做一次运算检查是否传来的签名与生成的签名是否相符,相符则验证通过。
写一段简单的代码演示一下

<?php
/**
 * 生成签名
 */
function makeSign($params, $secret_key) {
    // 将参数拼接成字符串
    $paramString = '';
    foreach ($params as $key to $value) {
        $paramString .= $key . '=' . $value;
    }
    
    // 参数字符串与secret_key做hash_hmac运算
    // 这里选用sha1算法
    $sign = hash_hmac('sha1', $paramString, $secret_key);
    return $sign;
}

/**
 * 检查签名
 */
function checkSign($params, $secret_key) {
    // 将参数内的sign提取,并销毁$params中的sign
    if (isset($params['sign'])) {
        $oldSign = $params['sign'];
        unset($params['sign']);
    } else {
        return false;
    }
    
    // 利用$params和$secret_key生成签名并检查
    $newSign = makeSign($params, $secret_key);
    
    return $oldSign == $newSign;
}

3. 可以加密解密的算法

其实就是通过mcrypt之类的拓展库,对请求参数进行加密,防止抓包获取请求参数。大致就是先将传参拼接成字符串,然后使用拓展库提供的方法将字符串加密,到目标服务器上对字符串解密获取请求参数。这块不多赘述,如果对传参安全有更高的要求,推荐使用这种方法。

使用拓展库的缺点是,正式环境上最好不要装这么多的拓展,以免影响服务器的运行速度(虽然现在服务器的性能都非常好)。而且遇到需要在开发或者部署中使用拓展库时,往往需要暂时停掉服务器,然后安装新的拓展,蛋疼。

关于签名

  1. 和小公司做对接时,永远不要相信文档!永远不要相信文档!永远不要相信文档!请直接和对方的技术人员沟通。

  2. 注意一下响应的格式和字符集,一般推荐在php代码前加一个header()函数强制把页面转换成json格式或者xml格式的文档。不加header可能没事,但是你也不知道对方服务器会出现什么问题。

  3. 如果一时半会你的签名验证完成不了,比如对方技术人员不在,无法及时解决接入问题,赶紧去写别的代码。签名验证是小事情,完成KPI才比较重要。