GeetestLib.php 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269
  1. <?php
  2. namespace addons\geetest\library;
  3. /**
  4. * 极验行为式验证安全平台,php 网站主后台包含的库文件
  5. *
  6. * @author Tanxu
  7. */
  8. class GeetestLib
  9. {
  10. const GT_SDK_VERSION = 'php_3.0.0';
  11. public static $connectTimeout = 1;
  12. public static $socketTimeout = 1;
  13. private $response;
  14. public function __construct($captcha_id, $private_key)
  15. {
  16. $this->captcha_id = $captcha_id;
  17. $this->private_key = $private_key;
  18. }
  19. /**
  20. * 判断极验服务器是否down机
  21. *
  22. * @param $param
  23. * @param int $new_captcha
  24. * @return int
  25. */
  26. public function pre_process($param, $new_captcha = 1)
  27. {
  28. $data = array('gt' => $this->captcha_id,
  29. 'new_captcha' => $new_captcha
  30. );
  31. $data = array_merge($data, $param);
  32. $query = http_build_query($data);
  33. $url = "http://api.geetest.com/register.php?" . $query;
  34. $challenge = $this->send_request($url);
  35. if (strlen($challenge) != 32) {
  36. $this->failback_process();
  37. return 0;
  38. }
  39. $this->success_process($challenge);
  40. return 1;
  41. }
  42. /**
  43. * @param $challenge
  44. */
  45. private function success_process($challenge)
  46. {
  47. $challenge = md5($challenge . $this->private_key);
  48. $result = array(
  49. 'success' => 1,
  50. 'gt' => $this->captcha_id,
  51. 'challenge' => $challenge,
  52. 'new_captcha' => 1
  53. );
  54. $this->response = $result;
  55. }
  56. /**
  57. *
  58. */
  59. private function failback_process()
  60. {
  61. $rnd1 = md5(rand(0, 100));
  62. $rnd2 = md5(rand(0, 100));
  63. $challenge = $rnd1 . substr($rnd2, 0, 2);
  64. $result = array(
  65. 'success' => 0,
  66. 'gt' => $this->captcha_id,
  67. 'challenge' => $challenge,
  68. 'new_captcha' => 1
  69. );
  70. $this->response = $result;
  71. }
  72. /**
  73. * @return mixed
  74. */
  75. public function get_response_str()
  76. {
  77. return json_encode($this->response);
  78. }
  79. /**
  80. * 返回数组方便扩展
  81. *
  82. * @return mixed
  83. */
  84. public function get_response()
  85. {
  86. return $this->response;
  87. }
  88. /**
  89. * 正常模式获取验证结果
  90. *
  91. * @param string $challenge
  92. * @param string $validate
  93. * @param string $seccode
  94. * @param array $param
  95. * @return int
  96. */
  97. public function success_validate($challenge, $validate, $seccode, $param, $json_format = 1)
  98. {
  99. if (!$this->check_validate($challenge, $validate)) {
  100. return 0;
  101. }
  102. $query = array(
  103. "seccode" => $seccode,
  104. "timestamp" => time(),
  105. "challenge" => $challenge,
  106. "captchaid" => $this->captcha_id,
  107. "json_format" => $json_format,
  108. "sdk" => self::GT_SDK_VERSION
  109. );
  110. $query = array_merge($query, $param);
  111. $url = "http://api.geetest.com/validate.php";
  112. $codevalidate = $this->post_request($url, $query);
  113. $obj = json_decode($codevalidate, true);
  114. if ($obj === false) {
  115. return 0;
  116. }
  117. if ($obj['seccode'] == md5($seccode)) {
  118. return 1;
  119. } else {
  120. return 0;
  121. }
  122. }
  123. /**
  124. * 宕机模式获取验证结果
  125. *
  126. * @param $challenge
  127. * @param $validate
  128. * @param $seccode
  129. * @return int
  130. */
  131. public function fail_validate($challenge, $validate, $seccode)
  132. {
  133. if (md5($challenge) == $validate) {
  134. return 1;
  135. } else {
  136. return 0;
  137. }
  138. }
  139. /**
  140. * @param $challenge
  141. * @param $validate
  142. * @return bool
  143. */
  144. private function check_validate($challenge, $validate)
  145. {
  146. if (strlen($validate) != 32) {
  147. return false;
  148. }
  149. if (md5($this->private_key . 'geetest' . $challenge) != $validate) {
  150. return false;
  151. }
  152. return true;
  153. }
  154. /**
  155. * GET 请求
  156. *
  157. * @param $url
  158. * @return mixed|string
  159. */
  160. private function send_request($url)
  161. {
  162. if (function_exists('curl_exec')) {
  163. $ch = curl_init();
  164. curl_setopt($ch, CURLOPT_URL, $url);
  165. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, self::$connectTimeout);
  166. curl_setopt($ch, CURLOPT_TIMEOUT, self::$socketTimeout);
  167. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  168. $data = curl_exec($ch);
  169. $curl_errno = curl_errno($ch);
  170. curl_close($ch);
  171. if ($curl_errno > 0) {
  172. return 0;
  173. } else {
  174. return $data;
  175. }
  176. } else {
  177. $opts = array(
  178. 'http' => array(
  179. 'method' => "GET",
  180. 'timeout' => self::$connectTimeout + self::$socketTimeout,
  181. )
  182. );
  183. $context = stream_context_create($opts);
  184. $data = @file_get_contents($url, false, $context);
  185. if ($data) {
  186. return $data;
  187. } else {
  188. return 0;
  189. }
  190. }
  191. }
  192. /**
  193. *
  194. * @param $url
  195. * @param string $postdata
  196. * @return mixed|string
  197. */
  198. private function post_request($url, $postdata = '')
  199. {
  200. if (!$postdata) {
  201. return false;
  202. }
  203. $data = http_build_query($postdata);
  204. if (function_exists('curl_exec')) {
  205. $ch = curl_init();
  206. curl_setopt($ch, CURLOPT_URL, $url);
  207. curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
  208. curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, self::$connectTimeout);
  209. curl_setopt($ch, CURLOPT_TIMEOUT, self::$socketTimeout);
  210. //不可能执行到的代码
  211. if (!$postdata) {
  212. curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
  213. } else {
  214. curl_setopt($ch, CURLOPT_POST, 1);
  215. curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
  216. }
  217. $data = curl_exec($ch);
  218. if (curl_errno($ch)) {
  219. $err = sprintf("curl[%s] error[%s]", $url, curl_errno($ch) . ':' . curl_error($ch));
  220. $this->triggerError($err);
  221. }
  222. curl_close($ch);
  223. } else {
  224. if ($postdata) {
  225. $opts = array(
  226. 'http' => array(
  227. 'method' => 'POST',
  228. 'header' => "Content-type: application/x-www-form-urlencoded\r\n" . "Content-Length: " . strlen($data) . "\r\n",
  229. 'content' => $data,
  230. 'timeout' => self::$connectTimeout + self::$socketTimeout
  231. )
  232. );
  233. $context = stream_context_create($opts);
  234. $data = file_get_contents($url, false, $context);
  235. }
  236. }
  237. return $data;
  238. }
  239. /**
  240. * @param $err
  241. */
  242. private function triggerError($err)
  243. {
  244. trigger_error($err);
  245. }
  246. }