优惠券订单及其他脚本

SpiUtils.php 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219
  1. <?php
  2. class SpiUtils{
  3. private static $top_sign_list = "HTTP_TOP_SIGN_LIST";
  4. private static $timestamp = "timestamp";
  5. private static $header_real_ip = array("X_Real_IP", "X_Forwarded_For", "Proxy_Client_IP",
  6. "WL_Proxy_Client_IP", "HTTP_CLIENT_IP", "HTTP_X_FORWARDED_FOR");
  7. /**
  8. * 校验SPI请求签名,适用于所有GET请求,及不包含文件参数的POST请求。
  9. *
  10. * @param request 请求对象
  11. * @param secret app对应的secret
  12. * @return true:校验通过;false:校验不通过
  13. */
  14. public static function checkSign4FormRequest($secret){
  15. return self::checkSign(null,null,$secret);
  16. }
  17. /**
  18. * 校验SPI请求签名,适用于请求体是xml/json等可用文本表示的POST请求。
  19. *
  20. * @param request 请求对象
  21. * @param body 请求体的文本内容
  22. * @param secret app对应的secret
  23. * @return true:校验通过;false:校验不通过
  24. */
  25. public static function checkSign4TextRequest($body,$secret){
  26. return self::checkSign(null,$body,$secret);
  27. }
  28. /**
  29. * 校验SPI请求签名,适用于带文件上传的POST请求。
  30. *
  31. * @param request 请求对象
  32. * @param form 除了文件参数以外的所有普通文本参数的map集合
  33. * @param secret app对应的secret
  34. * @return true:校验通过;false:校验不通过
  35. */
  36. public static function checkSign4FileRequest($form, $secret){
  37. return self::checkSign($form, null, $secret);
  38. }
  39. private static function checkSign($form, $body, $secret) {
  40. $params = array();
  41. // 1. 获取header参数
  42. $headerMap = self::getHeaderMap();
  43. foreach ($headerMap as $k => $v){
  44. $params[$k] = $v ;
  45. }
  46. // 2. 获取url参数
  47. $queryMap = self::getQueryMap();
  48. foreach ($queryMap as $k => $v){
  49. $params[$k] = $v ;
  50. }
  51. // 3. 获取form参数
  52. if ($form == null && $body == null) {
  53. $formMap = self::getFormMap();
  54. foreach ($formMap as $k => $v){
  55. $params[$k] = $v ;
  56. }
  57. } else if ($form != null) {
  58. foreach ($form as $k => $v){
  59. $params[$k] = $v ;
  60. }
  61. }
  62. if($body == null){
  63. $body = file_get_contents('php://input');
  64. }
  65. $remoteSign = $queryMap["sign"];
  66. $localSign = self::sign($params, $body, $secret);
  67. if (strcmp($remoteSign, $localSign) == 0) {
  68. return true;
  69. } else {
  70. $paramStr = self::getParamStrFromMap($params);
  71. self::logCommunicationError($remoteSign,$localSign,$paramStr,$body);
  72. return false;
  73. }
  74. }
  75. private static function getHeaderMap() {
  76. $headerMap = array();
  77. $signList = $_SERVER['HTTP_TOP_SIGN_LIST']; // 只获取参与签名的头部字段
  78. if(!$signList) {
  79. return $headerMap;
  80. }
  81. $signList = trim($signList);
  82. if (strlen($signList) > 0){
  83. $params = split(",", $signList);
  84. foreach ($_SERVER as $k => $v){
  85. if (substr($k, 0, 5) == 'HTTP_'){
  86. foreach($params as $kk){
  87. $upperkey = strtoupper($kk);
  88. if(self::endWith($k,$upperkey)){
  89. $headerMap[$kk] = $v;
  90. }
  91. }
  92. }
  93. }
  94. }
  95. return $headerMap;
  96. }
  97. private static function getQueryMap(){
  98. $queryStr = $_SERVER["QUERY_STRING"];
  99. $resultArray = array();
  100. foreach (explode('&', $queryStr) as $pair) {
  101. list($key, $value) = explode('=', $pair);
  102. if (strpos($key, '.') !== false) {
  103. list($subKey, $subVal) = explode('.', $key);
  104. if (preg_match('/(?P<name>\w+)\[(?P<index>\w+)\]/', $subKey, $matches)) {
  105. $resultArray[$matches['name']][$matches['index']][$subVal] = $value;
  106. } else {
  107. $resultArray[$subKey][$subVal] = urldecode($value);
  108. }
  109. } else {
  110. $resultArray[$key] = urldecode($value);
  111. }
  112. }
  113. return $resultArray;
  114. }
  115. private static function checkRemoteIp(){
  116. $remoteIp = $_SERVER["REMOTE_ADDR"];
  117. foreach ($header_real_ip as $k){
  118. $realIp = $_SERVER[$k];
  119. $realIp = trim($realIp);
  120. if(strlen($realIp) > 0 && strcasecmp("unknown",$realIp)){
  121. $remoteIp = $realIp;
  122. break;
  123. }
  124. }
  125. return self::startsWith($remoteIp,"140.205.144.") || self::startsWith($remoteIp,"40.205.145.");
  126. }
  127. private static function getFormMap(){
  128. $resultArray = array();
  129. foreach($_POST as $key=>$v) {
  130. $resultArray[$key] = $v ;
  131. }
  132. return $resultArray ;
  133. }
  134. private static function startsWith($haystack, $needle) {
  135. return $needle === "" || strpos($haystack, $needle) === 0;
  136. }
  137. private static function endWith($haystack, $needle) {
  138. $length = strlen($needle);
  139. if($length == 0)
  140. {
  141. return true;
  142. }
  143. return (substr($haystack, -$length) === $needle);
  144. }
  145. private static function checkTimestamp(){
  146. $ts = $_POST['timestamp'];
  147. if($ts){
  148. $clientTimestamp = strtotime($ts);
  149. $current = $_SERVER['REQUEST_TIME'];
  150. return ($current - $clientTimestamp) <= 5*60*1000;
  151. }else{
  152. return false;
  153. }
  154. }
  155. private static function getParamStrFromMap($params){
  156. ksort($params);
  157. $stringToBeSigned = "";
  158. foreach ($params as $k => $v)
  159. {
  160. if(strcmp("sign", $k) != 0)
  161. {
  162. $stringToBeSigned .= "$k$v";
  163. }
  164. }
  165. unset($k, $v);
  166. return $stringToBeSigned;
  167. }
  168. private static function sign($params,$body,$secret){
  169. ksort($params);
  170. $stringToBeSigned = $secret;
  171. $stringToBeSigned .= self::getParamStrFromMap($params);
  172. if($body)
  173. $stringToBeSigned .= $body;
  174. $stringToBeSigned .= $secret;
  175. return strtoupper(md5($stringToBeSigned));
  176. }
  177. protected static function logCommunicationError($remoteSign, $localSign, $paramStr, $body)
  178. {
  179. $localIp = isset($_SERVER["SERVER_ADDR"]) ? $_SERVER["SERVER_ADDR"] : "CLI";
  180. $logger = new TopLogger;
  181. $logger->conf["log_file"] = rtrim(TOP_SDK_WORK_DIR, '\\/') . '/' . "logs/top_comm_err_". date("Y-m-d") . ".log";
  182. $logger->conf["separator"] = "^_^";
  183. $logData = array(
  184. "checkTopSign error" ,
  185. "remoteSign=".$remoteSign ,
  186. "localSign=".$localSign ,
  187. "paramStr=".$paramStr ,
  188. "body=".$body
  189. );
  190. $logger->log($logData);
  191. }
  192. private static function clear_blank($str, $glue='')
  193. {
  194. $replace = array(" ", "\r", "\n", "\t"); return str_replace($replace, $glue, $str);
  195. }
  196. }
  197. ?>