'EOS', self::TYPE_ETH => 'ETH', self::TYPE_TRON => 'TRON', ]; public static function getAllType() { return self::$arrType; } public static function getTokenKey($token) { return self::PRE_KEY_TOKEN . $token; } /** * 检查token是否存在 * @param $player * * @return bool */ public static function checkToken() { $objRedis = dwRedis::init('dw_chat'); if ($_REQUEST['token'] && $_REQUEST['user_id']) { $token = $_REQUEST['token']; $user_id = $_REQUEST['user_id']; } else { $token = $_COOKIE['token']; $user_id = $_COOKIE['user_id']; } if ($token) { $tokenKey = self::getTokenKey($token); $value = $objRedis->get($tokenKey); if ($value) { if ($value == $user_id) { return true; } } else { self::clearCookie(); } } return false; } /** * 生成账号 */ public static function genToken($user_id) { $token = uuid16(); $tokenKey = self::getTokenKey($token); $objRedis = dwRedis::init(); // $objRedis->set($tokenKey, $account); $objRedis->setex($tokenKey, 86400, $user_id); return $token; } /** * 设置用户的Cookie * @param $account * * @return array */ public static function setCookie($user_id) { $token = Account::genToken($user_id); $expire = time() + 86400 * 7; $path = '/'; $domain = ''; if (ENV != ENV_DEV) { $domain = 'mee.chat'; } // 生成token setcookie('token', $token, $expire, $path, $domain); setcookie('user_id', $user_id, $expire, $path, $domain); return compact('user_id', 'token'); } public static function clearCookie() { $expire = time() - 86400; $path = '/'; // 删除正式环境的cookie setcookie('token', null, $expire, $path, 'mee.chat'); setcookie('user_id', null, $expire, $path, 'mee.chat'); if (ENV == ENV_DEV) { // 删除cookie setcookie('token', null, $expire, $path); setcookie('user_id', null, $expire, $path); } } public static function getRandomKey($account) { return self::PRE_KEY_RANDOM . $account; } private static function getAccessTokenKey($accessToken) { return self::PRE_KEY_ACCESS_TOKEN . $accessToken; } /** * 刷新access_token * @author solu * @param $random * @param null $objRedis * @return string */ private static function refreshAccessToken($random, $objRedis = null) { !$objRedis && $objRedis = dwRedis::init(); $accessToken = uuid(); $key = self::getAccessTokenKey($accessToken); $objRedis->setex($key, 900, $random); return $accessToken; } /** * 获取随机数 * @param $account * @param $withToken * @return string|array */ public static function getRandom($account, $withToken = false) { $objRedis = dwRedis::init(); $randomKey = self::getRandomKey($account); $random = $objRedis->get($randomKey); if (!$random) { // $random = uuid16(); $random = date('H:i:s ', time() - 8 * 3600) . rand(0, 999); } $objRedis->setex($randomKey, 900, $random); $accessToken = self::refreshAccessToken($random, $objRedis); return !$withToken ? $random : compact('random', 'accessToken'); } /** * 校验用户并且登录 * @author solu * @param $account * @param $random * @param $token * @return array * @throws Exception */ public static function verifyPlayer($account, $random, $token) { if (!$account) { throw new Exception('参数错误', CODE_PARAM_ERROR); } $objRedis = dwRedis::init(); $tokenKey = self::getAccessTokenKey($token); $storeRandom = $objRedis->get($tokenKey); if ($storeRandom != $random) { throw new Exception('access_token unmatch', CODE_PARAM_ERROR); } $user_id = User::login($account, Account::TYPE_EOS); return self::setCookie($user_id); } /** * 校验eos * @param $pubkey * @param $account * @param $data * @param $sign * @return bool * @throws Exception */ public static function verifyMsg($pubkey, $account, $data, $sign) { $json = EosBase::getAccount($account); $user = json_decode($json, true); // $user = EosRpcApi::getAccount($account); $active = $user['permissions'][0]['required_auth']['keys'][0]['key']; $owner = $user['permissions'][1]['required_auth']['keys'][0]['key']; if ($pubkey != $active && $pubkey != $owner) { throw new Exception('pubkey error', CODE_PARAM_ERROR); } $cmd = "node {$GLOBALS['verifyPath']} '$data' '$pubkey' '$sign'"; // 返回true表示验证通过 $ret = EosBase::execCmd($cmd); return trim($ret) == 'true'; } /** * 校验eth签名 * @author solu * @param $account * @param $data * @param $signed * @return bool * @throws Exception */ public static function verifyEth($account, $data, $signed) { $hash = Utils::sha3($data); $messageGmp = gmp_init($hash); $rHex = substr($signed, 2, 64); $sHex = substr($signed, 66, 64); $vValue = hexdec(substr($signed, 130, 2)); $r = $rHex; //hex string without 0x $s = $sHex; //hex string without 0x $v = $vValue; //27 or 28 $rGmp = gmp_init("0x" . $r); $sGmp = gmp_init("0x" . $s); $recovery = $v - 27; if ($recovery !== 0 && $recovery !== 1) { throw new Exception('Invalid signature v value'); } $publicKey = Signature::recoverPublicKey($rGmp, $sGmp, $messageGmp, $recovery); $publicKeyString = $publicKey["x"] . $publicKey["y"]; $recoveryAccount = '0x'. substr(self::keccak256(hex2bin($publicKeyString)), -40); return strtolower($recoveryAccount) == strtolower($account); } /** * 校验tron签名 * @author solu * @param $account * @param $data * @param $signed * @return bool */ public static function verifyTron($account, $data, $signed) { $data = Utils::sha3($data); $cmd = "node {$GLOBALS['tronVerifyPath']} '$data' '$signed' '$account'"; // 返回true表示验证通过 $ret = EosBase::execCmd($cmd); return trim($ret) == 'true'; } /** * keccak256 * @param $str * @return string * @throws Exception */ private static function keccak256($str) { return '0x'. Keccak::hash($str, 256); } }