Server/php/app_token.php (91 lines of code) (raw):
<?php
require_once 'sign_utils.php';
require_once 'compress_utils.php';
require_once 'app_token_options.php';
require_once 'bytes_utils.php';
require_once 'service.php';
class AppToken
{
private $app_id;
private $app_key;
private $timestamp;
private $issue_timestamp;
private $salt;
private $service;
private $options;
private $signature;
const VERSION_0 = "000";
public function __construct($app_id, $app_key, $timestamp, $issue_timestamp = null, $salt = null, $service = null, $options = null, $signature = null)
{
$this->app_id = $app_id;
$this->app_key = $app_key;
$this->timestamp = $timestamp;
$this->issue_timestamp = $issue_timestamp ?? time();
$this->salt = $salt ?? rand(1, $this->issue_timestamp);
$this->service = $service;
$this->options = $options;
$this->signature = $signature;
}
public function setService($service)
{
$this->service = $service;
}
public function setOptions($options)
{
$this->options = $options;
}
public function build()
{
if ($this->app_key === null) {
throw new ValueError('missing secretKey');
}
if ($this->service === null) {
throw new ValueError('missing service');
}
$signKey = generate_sign($this->app_key, $this->issue_timestamp, $this->salt);
$buf = '';
$app_id_bytes = $this->app_id;
$buf .= pack('N', strlen($app_id_bytes));
$buf .= $app_id_bytes;
$buf .= pack('N', $this->issue_timestamp);
$buf .= pack('N', $this->salt);
$buf .= pack('N', $this->timestamp);
$buf .= $this->service->pack();
if ($this->options === null) {
$this->options = new AppTokenOptions();
}
$buf .= $this->options->pack();
$fix_length_buf = getFixedLengthBytesAuto($buf);
$signature = sign($signKey, $fix_length_buf);
$token_buf = '';
$token_buf .= pack('N', strlen($signature));
$token_buf .= $signature;
$token_buf .= $fix_length_buf;
$fix_length_token_buf = getFixedLengthBytesAuto($token_buf);
return self::VERSION_0 . base64_encode(compress($fix_length_token_buf));
}
public static function parse($token): self
{
if ($token === null) {
throw new ValueError('empty appToken');
}
if (!substr($token, 0, strlen(self::VERSION_0)) == self::VERSION_0) {
throw new ValueError('unsupported version');
}
$token_buf = fopen("php://memory", 'r+');
assert($token_buf);
fwrite($token_buf, decompress(base64_decode(substr($token, strlen(self::VERSION_0)))));
rewind($token_buf);
$signature_length = unpack('N', fread($token_buf, 4))[1];
$signature = fread($token_buf, $signature_length);
$app_id_length = unpack('N', fread($token_buf, 4))[1];
$app_id = fread($token_buf, $app_id_length);
$issue_timestamp = unpack('N', fread($token_buf, 4))[1];
$salt = unpack('N', fread($token_buf, 4))[1];
$timestamp = unpack('N', fread($token_buf,4))[1];
$service = Service::unpack($token_buf);
$options = AppTokenOptions::unpack($token_buf);
fclose($token_buf);
return new self($app_id, null, $timestamp, $issue_timestamp, $salt, $service, $options, $signature);
}
}