Account.php 7.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. <?php
  2. /**
  3. * 用户基础信息
  4. * @author benzhan
  5. */
  6. use kornrunner\Keccak;
  7. class Account extends Model {
  8. protected $tableName = 'user_info';
  9. protected $dbKey = 'dw_chat';
  10. const PRE_KEY_TOKEN = 'globals:token:';
  11. const PRE_KEY_RANDOM = 'globals:random_1:';
  12. const PRE_KEY_ACCESS_TOKEN = 'globals:access_token:';
  13. const TYPE_EOS = 'eos';
  14. const TYPE_ETH = 'eth';
  15. const TYPE_TRON = 'tron';
  16. private static $arrType = [
  17. self::TYPE_EOS => 'EOS',
  18. self::TYPE_ETH => 'ETH',
  19. self::TYPE_TRON => 'TRON',
  20. ];
  21. public static function getAllType() {
  22. return self::$arrType;
  23. }
  24. public static function getTokenKey($token) {
  25. return self::PRE_KEY_TOKEN . $token;
  26. }
  27. /**
  28. * 检查token是否存在
  29. * @param $player
  30. *
  31. * @return bool
  32. */
  33. public static function checkToken() {
  34. $objRedis = dwRedis::init('dw_chat');
  35. $token = $_REQUEST['token'];
  36. $user_id = $_REQUEST['user_id'];
  37. // if ($_REQUEST['token'] && $_REQUEST['user_id']) {
  38. // $token = $_REQUEST['token'];
  39. // $user_id = $_REQUEST['user_id'];
  40. // } else {
  41. // $token = $_COOKIE['token'];
  42. // $user_id = $_COOKIE['user_id'];
  43. // }
  44. if ($token) {
  45. $tokenKey = self::getTokenKey($token);
  46. $value = $objRedis->get($tokenKey);
  47. if ($value) {
  48. if ($value == $user_id) {
  49. return true;
  50. }
  51. } else {
  52. self::clearCookie();
  53. }
  54. }
  55. return false;
  56. }
  57. /**
  58. * 生成账号
  59. */
  60. public static function genToken($user_id) {
  61. $token = uuid16();
  62. $tokenKey = self::getTokenKey($token);
  63. $objRedis = dwRedis::init();
  64. // $objRedis->set($tokenKey, $account);
  65. $objRedis->setex($tokenKey, 86400, $user_id);
  66. return $token;
  67. }
  68. /**
  69. * 设置用户的Cookie
  70. * @param $account
  71. *
  72. * @return array
  73. */
  74. public static function setCookie($user_id) {
  75. $token = Account::genToken($user_id);
  76. // 不再设置cookie
  77. // $expire = time() + 86400 * 7;
  78. // $path = '/';
  79. // $domain = '';
  80. // if (ENV != ENV_DEV) {
  81. // $domain = 'mee.chat';
  82. // }
  83. //
  84. // // 生成token
  85. // setcookie('token', $token, $expire, $path, $domain);
  86. // setcookie('user_id', $user_id, $expire, $path, $domain);
  87. return compact('user_id', 'token');
  88. }
  89. public static function clearCookie() {
  90. $expire = time() - 86400;
  91. $path = '/';
  92. // 删除正式环境的cookie
  93. setcookie('token', null, $expire, $path, 'mee.chat');
  94. setcookie('user_id', null, $expire, $path, 'mee.chat');
  95. if (ENV == ENV_DEV) {
  96. // 删除cookie
  97. setcookie('token', null, $expire, $path);
  98. setcookie('user_id', null, $expire, $path);
  99. }
  100. }
  101. public static function getRandomKey($account) {
  102. return self::PRE_KEY_RANDOM . $account;
  103. }
  104. private static function getAccessTokenKey($accessToken) {
  105. return self::PRE_KEY_ACCESS_TOKEN . $accessToken;
  106. }
  107. /**
  108. * 刷新access_token
  109. * @author solu
  110. * @param $random
  111. * @param null $objRedis
  112. * @return string
  113. */
  114. private static function refreshAccessToken($random, $objRedis = null) {
  115. !$objRedis && $objRedis = dwRedis::init();
  116. $accessToken = uuid();
  117. $key = self::getAccessTokenKey($accessToken);
  118. $objRedis->setex($key, 900, $random);
  119. return $accessToken;
  120. }
  121. /**
  122. * 获取随机数
  123. * @param $account
  124. * @param $withToken
  125. * @return string|array
  126. */
  127. public static function getRandom($account, $withToken = false) {
  128. $objRedis = dwRedis::init();
  129. $randomKey = self::getRandomKey($account);
  130. $random = $objRedis->get($randomKey);
  131. if (!$random) {
  132. // $random = uuid16();
  133. $random = date('H:i:s ', time() - 8 * 3600) . rand(0, 999);
  134. }
  135. $objRedis->setex($randomKey, 900, $random);
  136. $accessToken = self::refreshAccessToken($random, $objRedis);
  137. return !$withToken ? $random : compact('random', 'accessToken');
  138. }
  139. /**
  140. * 校验用户并且登录
  141. * @author solu
  142. * @param $account
  143. * @param $random
  144. * @param $token
  145. * @return array
  146. * @throws Exception
  147. */
  148. public static function verifyPlayer($account, $random, $token) {
  149. if (!$account) {
  150. throw new Exception('参数错误', CODE_PARAM_ERROR);
  151. }
  152. $objRedis = dwRedis::init();
  153. $tokenKey = self::getAccessTokenKey($token);
  154. $storeRandom = $objRedis->get($tokenKey);
  155. if ($storeRandom != $random) {
  156. throw new Exception('access_token unmatch', CODE_PARAM_ERROR);
  157. }
  158. $user_id = User::login($account, Account::TYPE_EOS);
  159. return self::setCookie($user_id);
  160. }
  161. /**
  162. * 校验eos
  163. * @param $pubkey
  164. * @param $account
  165. * @param $data
  166. * @param $sign
  167. * @return bool
  168. * @throws Exception
  169. */
  170. public static function verifyMsg($pubkey, $account, $data, $sign) {
  171. $json = EosBase::getAccount($account);
  172. $user = json_decode($json, true);
  173. // $user = EosRpcApi::getAccount($account);
  174. $active = $user['permissions'][0]['required_auth']['keys'][0]['key'];
  175. $owner = $user['permissions'][1]['required_auth']['keys'][0]['key'];
  176. if ($pubkey != $active && $pubkey != $owner) {
  177. throw new Exception('pubkey error', CODE_PARAM_ERROR);
  178. }
  179. $cmd = "node {$GLOBALS['verifyPath']} '$data' '$pubkey' '$sign'";
  180. // 返回true表示验证通过
  181. $ret = EosBase::execCmd($cmd);
  182. return trim($ret) == 'true';
  183. }
  184. /**
  185. * 校验eth签名
  186. * @author solu
  187. * @param $account
  188. * @param $data
  189. * @param $signed
  190. * @return bool
  191. * @throws Exception
  192. */
  193. public static function verifyEth($account, $data, $signed) {
  194. $hash = Utils::sha3($data);
  195. $messageGmp = gmp_init($hash);
  196. $rHex = substr($signed, 2, 64);
  197. $sHex = substr($signed, 66, 64);
  198. $vValue = hexdec(substr($signed, 130, 2));
  199. $r = $rHex; //hex string without 0x
  200. $s = $sHex; //hex string without 0x
  201. $v = $vValue; //27 or 28
  202. $rGmp = gmp_init("0x" . $r);
  203. $sGmp = gmp_init("0x" . $s);
  204. $recovery = $v - 27;
  205. if ($recovery !== 0 && $recovery !== 1) {
  206. throw new Exception('Invalid signature v value');
  207. }
  208. $publicKey = Signature::recoverPublicKey($rGmp, $sGmp, $messageGmp, $recovery);
  209. $publicKeyString = $publicKey["x"] . $publicKey["y"];
  210. $recoveryAccount = '0x'. substr(self::keccak256(hex2bin($publicKeyString)), -40);
  211. return strtolower($recoveryAccount) == strtolower($account);
  212. }
  213. /**
  214. * 校验tron签名
  215. * @author solu
  216. * @param $account
  217. * @param $data
  218. * @param $signed
  219. * @return bool
  220. */
  221. public static function verifyTron($account, $data, $signed) {
  222. $data = Utils::sha3($data);
  223. $cmd = "node {$GLOBALS['tronVerifyPath']} '$data' '$signed' '$account'";
  224. // 返回true表示验证通过
  225. $ret = EosBase::execCmd($cmd);
  226. return trim($ret) == 'true';
  227. }
  228. /**
  229. * keccak256
  230. * @param $str
  231. * @return string
  232. * @throws Exception
  233. */
  234. private static function keccak256($str) {
  235. return '0x'. Keccak::hash($str, 256);
  236. }
  237. }