在我们正常的业务中,第三方对接总能遇到。那么,如何判定是对方,又不影响使用,维护起来还方便呢。
以前经常使用token+redis有效期的方式进行验证(因为需要和移动端对接,登录验证),但是这种方式在一些单纯的不要登录的接口对接中维护起来太复杂繁琐。
这里就需要一种比较简单又可行的签名方式验证了,当然,只要你的签名规则不要泄露就没问题啦,上代码吧
/** * 统一签名规则 * @param array $params * @param string $secretKey * @return string * @throws Exception */ private static function signRule(array $params, string $secretKey){ if(empty($params)){ Error::error('signRule params is empty'); } if(empty($secretKey)){ Error::error('signRule secretKey is empty'); } ksort($params); $arr = array_merge([ 'secretKey' => $secretKey, ], $params); $sign = md5(json_encode(http_build_query($arr))); unset($arr); return $sign; } /** * 统一验签方法 * @param string $sign 此签名为参数$params,通过函数signRule规则获取而来 * @param array $params * @param string $secretKey * @return bool * @throws Exception */ public static function sign(string $sign, array $params, string $secretKey) { if(empty($params)){ Error::error('sign params is empty'); } if(!isset($params['timestamp']) || !$params['timestamp']){ Error::error('发送的数据参数不合法'); } if(empty($secretKey)){ Error::error('sign secretKey is empty'); } // 验证请求, 10分钟失效 if ((time() - $params['timestamp']) > 600) { Error::error('验证失效, 请重新发送请求'); } $_sign = self::signRule($params,$secretKey); if ($_sign != $sign) { return false; } return true; } /** * 加签 * @param array $params * @param string $secretKey * @return string * @throws Exception */ public static function addSign(array $params, string $secretKey){ if(empty($params)){ Error::error('addSign params is empty'); } if(empty($secretKey)){ Error::error('addSign secretKey is empty'); } return self::signRule($params,$secretKey); }
note:$secretKey密钥很重要,双方的相同只要一方丢失就不好了。
这样的好处是:
a、唯一性,签名是唯一的,可验证目标用户
b、可变性,每次携带的签名必须是变化的
c、时效性,具有一定的时效,过期作废
d、完整性,能够对数据包进行验证,防止篡改
网上看到了很多人写的,有的规则很简单,我这里添加了一些其他的规则方式,其实也都一样。