国家虚拟仿真实验教学项目共享平台(实验空间)PHP SDK
使用XJWT标准,此标准基于JSON Web Token (JWT)开发。XJWT包含三个参数:header, payload, signature,因此生成token就要先获得这三个参数。
class IlabJwt { public $TYPE_RESERVED = 0; public $TYPE_JSON = 1; public $TYPE_SYS = 2; public static $enableLog = true; public static $logger = null; public $appName = 'test'; public $issuerId = 100400; public $secretKey = '16jmp2'; public $aesKey = 'SbYymvfZ8UjEmShxRAB0b1Dtaa0uGjDOOJa/f0Mbuo4='; public function is_64bit() { $int = "9223372036854775807"; $int = intval($int); if ($int == "9223372036854775807") { /* 64bit */ return 'J'; }elseif ($int == 2147483647) { /* 32bit */ exit('请使用64位的 PHP'); }else{ /* error */ return 'error'; } } public function getJwt($body) { $body = json_encode($body, JSON_UNESCAPED_UNICODE); //JSON_UNESCAPED_UNICODE 必须 $header = $this->packHeader(); $body = $this->encrypt($body); $base64Header = base64_encode($header); $base64Payload = base64_encode($body); $base64Signature = base64_encode($this->sign($base64Header, $base64Payload)); $xjwt = urlencode($base64Header.'.'.$base64Payload.'.'.$base64Signature); return $xjwt; } public function packHeader() { $header = ''; $expiry = round((microtime(true) + 900) * 1000); //900秒过期时间 $header .= pack($this->is_64bit(), $expiry); $type = pack('n', $this->TYPE_JSON); $header .= $type[1]; $header .= pack($this->is_64bit(), $this->issuerId); return $header; } public function encrypt($body) { $payload = ''; //前接8字节随机整数 $randLong = pack($this->is_64bit(), rand(0, PHP_INT_MAX)); $payload .= $randLong; $payload .= $body; //补齐为64字节的整数倍 $tempLen = strlen($payload) + 1; $paddingLen = 16 - $tempLen % 16; $padding = str_pad('', $paddingLen + 1, pack('c', $paddingLen)); $payload .= $padding; //aes加密 $aesKey = base64_decode($this->aesKey); $iv = substr($aesKey, 0, 16); $payload = openssl_encrypt($payload, 'AES-256-CBC', $aesKey, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING, $iv); return $payload; } public function sign($base64Header, $base64Payload) { $signature = hash_hmac('sha256', $base64Header . '.' . $base64Payload, $this->secretKey, true); return $signature; } public function getBody($jwt) { list($base64Header, $base64Payload, $base64Signature) = explode('.', $jwt); $header = base64_decode($base64Header); $payload = base64_decode($base64Payload); $signature = base64_decode($base64Signature); if (!$this->validateSignature($signature, $base64Header, $base64Payload)) { // var_dump('Signature is invalid.'); var_dump('Signature is invalid.'); return 'error:Signature is invalid.'; } //header:expiry $expiry = substr($header, 0, 8); if ($this->isExpired($expiry)) { var_dump('Data is expired.'); return 'error:Data is expired.'; } //header:type $type = substr($header, 8, 1); if (!$this->isValidType($type)) { var_dump('Type is invalid.'); return 'error:Type is invalid.'; } //header:issuerid $issuerId = substr($header, 9); if (!$this->isValidIssuer($issuerId)) { var_dump('Issuer is invalid.'); return 'error:Issuer is invalid.'; } //payload $body = $this->decrypt($payload); if (!$body) { return 'error:The wrong payload'; } //['id' => xxx, 'un' => 'xxx', 'dis' => 'xxx'] return json_decode($body, true); } public function isExpired($expiry) { $expiry = unpack($this->is_64bit(), $expiry); $expiry = $expiry[1] / 1000; var_dump('Expiry : ' . date("Y-m-d H:i:s",intval($expiry))); return (time() < $expiry); } public function isValidType($type) { $type = unpack('n', "\0" . $type); $type = $type[1]; var_dump('Type : ' . $type); return $type === $this->TYPE_JSON; } public function isValidIssuer($issuerId) { $issuerId = unpack($this->is_64bit(), $issuerId); $issuerId = $issuerId[1]; var_dump('IssuerId : ' . $issuerId); return $issuerId === $this->issuerId; } public function decrypt($payload) { $aesKey = base64_decode($this->aesKey); $iv = substr($aesKey, 0, 16); $data = openssl_decrypt($payload, 'AES-256-CBC', $aesKey, OPENSSL_RAW_DATA | OPENSSL_NO_PADDING, $iv); $dataLen = strlen($data); $paddingLen = unpack('n', "\0" . $data[$dataLen - 1]); $paddingLen = $paddingLen[1]; $body = substr($data, 8, - $paddingLen - 1); var_dump('Body : ' . $body); return $body; } public function validateSignature($signature, $base64Header, $base64Payload) { $caculatedSignature = $this->sign($base64Header, $base64Payload); var_dump('Caculated signature (base64 code) : ' . base64_encode($caculatedSignature) . ', received signature (base64 code) : ' . base64_encode($signature)); return (base64_encode($caculatedSignature) === base64_encode($signature)); } public function log($message, $type = 'info', $errno = null, $error = '', $file = null) { return; } }
使用方法:
$token = (string)$_GET['token']; $ilab = new IlabJwt(); $result = $ilab->getBody($token); var_dump($result); #技术支持 方倍工作室
示例:
http://www.fangbei.org/tests/Ilab.php?token=AAABbRVKvGoBAAAAAAABiDA%3D.FN8Stlr2dWWsswAOq%2FlcJSboAOwzXGSb0nzPV7Ek1eiDBRJOT%2BZgllMiIwI4CtylOMrs6TaIW2HIeRxEqpwdM79SBpwuRbiyW4mLudHVrsHm1v2A7z1DYaUHpMZK%2BGF3u2l6CzMGTDvsQgOL4TUxPYwSN6%2FpC8k1szv36UIPAXydfK9vfDCIE%2FpwIU6XJVOrGGT8AFVfxNWn40%2FYDUTfpzoI8Cd09ZpxFqIxu8cQFu%2FhMDfUZ5F1jk2y%2FUOUW0zMR62SnVRKCr8YGUQV39oNlCQRSYrzJApXfpeVJNC1%2FyomujpfWWReJLP1QiMKnzoDARhAhRL%2BtODL1yXQQoUIJg%3D%3D.qmxiLXrOBDMVSInTgs%2B944v7Jf9YZ8stPAcEubfvCgQ%3D
返回
array(5) { ["id"]=> int(854) ["un"]=> string(5) "test4" ["dis"]=> string(18) "实验空间测试" ["orderId"]=> string(0) "" ["key"]=> string(172) "6bvL4uSUhZPCpKaSa8hA400uusujXi8HqP/dTRFjWA6EoSOBjnXzIcg9C0DhG6SaHYbSDuoX6pTvnIbP6wDGm2tjZClJNxpPLHR693dznJCBrwi7hFRlFeSdehBuE+BMRc1NDWoXNCEeDXbrOs2UblO5UqMbGk+WRL3gudRnIlw=" }
本文来自博客园,作者:方倍工作室,转载请注明原文链接:https://www.cnblogs.com/txw1958/p/ilab-php-sdk.html