API接口签名验证方案

主要是和外部合作的时候需要考虑的安全性问题,首先是必须走HTTPS不多说,其次是接口上需要添加相应的校验,基本思路是给请求的参数添加个校验参数,不过实际做法各不一样,这里记录下我碰到的几种模式以及我自己的思考

参数签名模式

通用接口,仅仅添加一个校验参数,sign值是其他所有参数按照校验算法计算出来的(需要要加个不在URL参数里面带的密钥)这种对 GET 和 POST 都是类似的

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/**
* 密钥生成算法
* @param array $params 需要加密的参数对(一般是url的参数)
* string $sha1 密钥
* @return string
*/
public static function getIntSign($params, $sha1) {
ksort ( $params, SORT_STRING ); // 对参数的key以字母顺序排序
$paramsArr = array ();
foreach ( $params as $pkey => $pval ) {
if ($pkey == "token" || $pkey == "log_id") {
continue;
}
array_push ( $paramsArr, ($pkey . ":" . $pval) ); // 用冒号连结参数的key和val
}
$hashString = implode ( "_", $paramsArr ); // 用下划线连结各参数(key,val)对
$hashString = $hashString . "_" . $sha1; // 在最后加上有效的sha1值
$intSign = sha1 ( $hashString );
return $intSign;
}

校验也很简单,把所有参数丢到生成算法里面,计算下和sign值结果是不是一样的就行了

还看到一个微服务提供给不同的app,略有不同

  1. URL参数里面带上分配的appkey
  2. 对于post的请求,需要对post体进行校验比如md5下生成checkStr
  3. 同样需要个sign值 对get的参数进行 appkey+checkStr 生成sign

唯一性保证

在上面的基础上添加timestamp,服务端看这个timestamp 不能超过指定时间长度,超过失效。这个对更新类的请求有用,别人不能重复发请求获取最新数据。