Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| c095b69f67 | |||
| 4c8c5ac239 | |||
| cfc847133e | |||
| 30b430f1cf | |||
| 516c7612a5 | |||
| 3bb3d5a1d7 | |||
| fb48a0b508 | |||
| a3964faa72 | |||
| 0fea7ac770 | |||
| 7eccee5d16 | |||
| 565943b76f |
+4
-4
@@ -261,7 +261,7 @@ class Db implements ISqlBuilder
|
||||
if (empty($db)) {
|
||||
$db = Snowflake::app()->get('db');
|
||||
}
|
||||
return $db->createCommand('DROP TABLE ' . $table)->delete();
|
||||
return $db->createCommand('DROP TABLE `' . $db->database . '`.' . $table)->delete();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -277,7 +277,7 @@ class Db implements ISqlBuilder
|
||||
$db = Snowflake::app()->get('db');
|
||||
}
|
||||
|
||||
return $db->createCommand('TRUNCATE ' . $table)->exec();
|
||||
return $db->createCommand('TRUNCATE `' . $db->database . '`.' . $table)->exec();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -298,7 +298,7 @@ class Db implements ISqlBuilder
|
||||
return null;
|
||||
}
|
||||
|
||||
return $db->createCommand('SHOW CREATE TABLE ' . $table)->one();
|
||||
return $db->createCommand('SHOW CREATE TABLE `' . $db->database . '`.' . $table)->one();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -317,7 +317,7 @@ class Db implements ISqlBuilder
|
||||
return null;
|
||||
}
|
||||
|
||||
return $db->createCommand('SHOW FULL FIELDS FROM ' . $table)->all();
|
||||
return $db->createCommand('SHOW FULL FIELDS FROM `' . $db->database . '`.' . $table)->all();
|
||||
}
|
||||
|
||||
|
||||
|
||||
+3
-3
@@ -12,9 +12,6 @@ namespace Gii;
|
||||
use Database\Connection;
|
||||
use Database\Db;
|
||||
use Exception;
|
||||
use JetBrains\PhpStorm\ArrayShape;
|
||||
|
||||
use Snowflake\Abstracts\Config;
|
||||
use Snowflake\Abstracts\Input;
|
||||
use Snowflake\Exception\ComponentException;
|
||||
use Snowflake\Exception\ConfigException;
|
||||
@@ -42,6 +39,9 @@ class Gii
|
||||
public string $controllerNamespace = 'App\\Http\\Controllers\\';
|
||||
|
||||
|
||||
public static array $createSqls = [];
|
||||
|
||||
|
||||
public array $keyword = [
|
||||
'ADD', 'ALL', 'ALTER', 'AND', 'AS', 'ASC', 'ASENSITIVE', 'BEFORE', 'BETWEEN', 'BIGINT', 'BINARY', 'BLOB', 'BOTH', 'BY', 'CALL', 'CASCADE', 'CASE', 'CHANGE', 'CHAR', 'CHARACTER', 'CHECK', 'COLLATE', 'COLUMN', 'CONDITION', 'CONNECTION', 'CONSTRAINT', 'CONTINUE', 'CONVERT', 'CREATE', 'CROSS', 'CURRENT_DATE', 'CURRENT_TIME', 'CURRENT_TIMESTAMP', 'CURRENT_USER', 'CURSOR', 'DATABASE', 'DATABASES', 'DAY_HOUR', 'DAY_MICROSECOND', 'DAY_MINUTE', 'DAY_SECOND', 'DEC', 'DECIMAL', 'DECLARE', 'DEFAULT', 'DELAYED', 'DELETE', 'DESC', 'DESCRIBE', 'DETERMINISTIC', 'DISTINCT', 'DISTINCTROW', 'DIV', 'DOUBLE', 'DROP', 'DUAL', 'EACH', 'ELSE', 'ELSEIF', 'ENCLOSED', 'ESCAPED', 'EXISTS', 'EXIT', 'EXPLAIN', 'FALSE', 'FETCH', 'FLOAT', 'FLOAT4', 'FLOAT8', 'FOR', 'FORCE', 'FOREIGN', 'FROM', 'FULLTEXT', 'GOTO', 'GRANT', 'GROUP', 'HAVING', 'HIGH_PRIORITY', 'HOUR_MICROSECOND', 'HOUR_MINUTE', 'HOUR_SECOND', 'IF', 'IGNORE', 'IN', 'INDEX', 'INFILE', 'INNER', 'INOUT', 'INSENSITIVE', 'INSERT', 'INT', 'INT1', 'INT2', 'INT3', 'INT4', 'INT8', 'INTEGER', 'INTERVAL', 'INTO', 'IS', 'ITERATE', 'JOIN', 'KEY', 'KEYS', 'KILL', 'LABEL', 'LEADING', 'LEAVE', 'LEFT', 'LIKE', 'LIMIT', 'LINEAR', 'LINES', 'LOAD', 'LOCALTIME', 'LOCALTIMESTAMP', 'LOCK', 'LONG', 'LONGBLOB', 'LONGTEXT', 'LOOP', 'LOW_PRIORITY', 'MATCH', 'MEDIUMBLOB', 'MEDIUMINT', 'MEDIUMTEXT', 'MIDDLEINT', 'MINUTE_MICROSECOND', 'MINUTE_SECOND', 'MOD', 'MODIFIES', 'NATURAL', 'NOT', 'NO_WRITE_TO_BINLOG', 'NULL', 'NUMERIC', 'ON', 'OPTIMIZE', 'OPTION', 'OPTIONALLY', 'OR', 'ORDER', 'OUT', 'OUTER', 'OUTFILE', 'PRECISION', 'PRIMARY', 'PROCEDURE', 'PURGE', 'RAID0', 'RANGE', 'READ', 'READS', 'REAL', 'REFERENCES', 'REGEXP', 'RELEASE', 'RENAME', 'REPEAT', 'REPLACE', 'REQUIRE', 'RESTRICT', 'RETURN', 'REVOKE', 'RIGHT', 'RLIKE', 'SCHEMA', 'SCHEMAS', 'SECOND_MICROSECOND', 'SELECT', 'SENSITIVE', 'SEPARATOR', 'SET', 'SHOW', 'SMALLINT', 'SPATIAL', 'SPECIFIC', 'SQL', 'SQLEXCEPTION', 'SQLSTATE', 'SQLWARNING', 'SQL_BIG_RESULT', 'SQL_CALC_FOUND_ROWS', 'SQL_SMALL_RESULT', 'SSL', 'STARTING', 'STRAIGHT_JOIN', 'TABLE', 'TERMINATED', 'THEN', 'TINYBLOB', 'TINYINT', 'TINYTEXT', 'TO', 'TRAILING', 'TRIGGER', 'TRUE', 'UNDO', 'UNION', 'UNIQUE', 'UNLOCK', 'UNSIGNED', 'UPDATE', 'USAGE', 'USE', 'USING', 'UTC_DATE', 'UTC_TIME', 'UTC_TIMESTAMP', 'VALUES', 'VARBINARY', 'VARCHAR', 'VARCHARACTER', 'VARYING', 'WHEN', 'WHERE', 'WHILE', 'WITH', 'WRITE', 'X509', 'XOR', 'YEAR_MONTH', 'ZEROFILL'
|
||||
];
|
||||
|
||||
+20
-12
@@ -22,12 +22,12 @@ class GiiModel extends GiiBase
|
||||
public ?array $fields;
|
||||
|
||||
/**
|
||||
* ModelFile constructor.
|
||||
* @param $classFileName
|
||||
* @param $tableName
|
||||
* @param $visible
|
||||
* @param $res
|
||||
* @param $fields
|
||||
* GiiModel constructor.
|
||||
* @param string $classFileName
|
||||
* @param string $tableName
|
||||
* @param array $visible
|
||||
* @param array $res
|
||||
* @param array $fields
|
||||
*/
|
||||
public function __construct(string $classFileName, string $tableName, array $visible, array $res, array $fields)
|
||||
{
|
||||
@@ -308,16 +308,20 @@ use Database\ActiveRecord;
|
||||
if (empty($data)) return '';
|
||||
$string = [];
|
||||
foreach ($data as $key => $_val) {
|
||||
if (is_string($key) && str_contains($key, ',')) {
|
||||
$key = '[' . $key . ']';
|
||||
if (in_array($_val[0][1], $this->type['float'])) {
|
||||
$e_x = explode(',', $key);
|
||||
$key = '\'round\' => ' . $e_x[1] . ', \'maxLength\' => ' . ((int)$e_x[0] + 1);
|
||||
} else if (is_string($key) && str_contains($key, ',')) {
|
||||
$key = '\'between\' => [' . $key . ']';
|
||||
} else {
|
||||
$key = '\'maxLength\' => ' . $key;
|
||||
}
|
||||
if (count($_val) == 1) {
|
||||
[$typeRule, $type, $rule, $field] = current($_val);
|
||||
$_tmp = '
|
||||
[\'' . $field . '\', \'' . ($type == 'enum' ? 'enum' : 'maxLength') . '\' => ' . $key . ']';
|
||||
[\'' . $_val[0][3] . '\', ' . ($_val[0][1] == 'enum' ? '\'enum\' => ' . $key : $key) . ']';
|
||||
} else {
|
||||
$_tmp = '
|
||||
[[\'' . implode('\', \'', array_column($_val, 3)) . '\'], \'maxLength\' => ' . $key . ']';
|
||||
[[\'' . implode('\', \'', array_column($_val, 3)) . '\'], ' . $key . ']';
|
||||
}
|
||||
$string[] = $_tmp;
|
||||
}
|
||||
@@ -412,6 +416,10 @@ use Database\ActiveRecord;
|
||||
*/
|
||||
private function setCreateSql($table): string
|
||||
{
|
||||
if (isset(Gii::$createSqls[$table])) {
|
||||
return Gii::$createSqls[$table];
|
||||
}
|
||||
|
||||
$text = Db::showCreateSql($table, $this->db)['Create Table'] ?? '';
|
||||
|
||||
$_tmp = [];
|
||||
@@ -419,7 +427,7 @@ use Database\ActiveRecord;
|
||||
$_tmp[] = '// ' . $val;
|
||||
}
|
||||
|
||||
return implode(PHP_EOL, $_tmp);
|
||||
return Gii::$createSqls[$table] = implode(PHP_EOL, $_tmp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -22,7 +22,7 @@ abstract class HttpService extends Component
|
||||
* @param string $category
|
||||
* @throws Exception
|
||||
*/
|
||||
protected function write($message, $category = 'app')
|
||||
protected function write($message, string $category = 'app')
|
||||
{
|
||||
$logger = Snowflake::app()->getLogger();
|
||||
$logger->write($message, $category);
|
||||
|
||||
@@ -150,12 +150,12 @@ class Response extends HttpService
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|null $context
|
||||
* @param mixed $context
|
||||
* @param int $statusCode
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
public function send(?string $context = '', int $statusCode = 200): mixed
|
||||
public function send(mixed $context = '', int $statusCode = 200): mixed
|
||||
{
|
||||
$sendData = $this->parseData($context);
|
||||
|
||||
|
||||
@@ -35,7 +35,6 @@ use function Co\run;
|
||||
* @package Snowflake
|
||||
*
|
||||
* @property-read Config $config
|
||||
* @property-read WchatProviders $wchat
|
||||
*/
|
||||
class Application extends BaseApplication
|
||||
{
|
||||
@@ -62,6 +61,9 @@ class Application extends BaseApplication
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* @param Closure|array $closure
|
||||
* @return $this
|
||||
|
||||
+386
-366
@@ -5,11 +5,12 @@ namespace Snowflake\Jwt;
|
||||
|
||||
use Exception;
|
||||
use HttpServer\Http\HttpHeaders;
|
||||
use Snowflake\Cache\Redis;
|
||||
use Snowflake\Abstracts\Component;
|
||||
use Snowflake\Abstracts\Config;
|
||||
use Snowflake\Cache\Redis;
|
||||
use Snowflake\Core\Json;
|
||||
use Snowflake\Core\Str;
|
||||
use Snowflake\Exception\AuthException;
|
||||
use Snowflake\Abstracts\Component;
|
||||
use Snowflake\Exception\ConfigException;
|
||||
use Snowflake\Snowflake;
|
||||
|
||||
@@ -21,20 +22,20 @@ use Snowflake\Snowflake;
|
||||
class Jwt extends Component
|
||||
{
|
||||
|
||||
/** @var int $user */
|
||||
private int $user;
|
||||
/** @var int $user */
|
||||
private int $user;
|
||||
|
||||
private array $data;
|
||||
private array $data;
|
||||
|
||||
private array $source = ['browser', 'android', 'iphone', 'pc', 'mingame'];
|
||||
private array $source = ['browser', 'android', 'iphone', 'pc', 'mingame'];
|
||||
|
||||
private array $config = ['token' => ''];
|
||||
private array $config = ['token' => ''];
|
||||
|
||||
private ?int $timeout = 7200;
|
||||
private ?int $timeout = 7200;
|
||||
|
||||
private string $key = 'www.xshucai.com';
|
||||
private string $key = 'www.xshucai.com';
|
||||
|
||||
private ?string $public = '-----BEGIN PUBLIC KEY-----
|
||||
private ?string $public = '-----BEGIN PUBLIC KEY-----
|
||||
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6BuML3gtLGde7QKNuNST
|
||||
UCB9gdHC7XIpOc7Wx2I64Esj3UxWHTgp3URj0ge8zpy7A3FfBdppR7d1nwoD6Xad
|
||||
jqfjEWpTy4WwGYsOfH0tFl3wAmse0lebF4NFsS9pzrikQT6c9qsVm88pCjvg4i5t
|
||||
@@ -44,7 +45,7 @@ WlQhpQrA5/wKd76dCzjvqw9M32OiZl2lCKT73cV8GUvt7BNsM1SiPhqfY7nhO6y3
|
||||
cwIDAQAB
|
||||
-----END PUBLIC KEY-----';
|
||||
|
||||
private ?string $private = '-----BEGIN RSA PRIVATE KEY-----
|
||||
private ?string $private = '-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpQIBAAKCAQEA6BuML3gtLGde7QKNuNSTUCB9gdHC7XIpOc7Wx2I64Esj3UxW
|
||||
HTgp3URj0ge8zpy7A3FfBdppR7d1nwoD6XadjqfjEWpTy4WwGYsOfH0tFl3wAmse
|
||||
0lebF4NFsS9pzrikQT6c9qsVm88pCjvg4i5tWhTMEnpTFDYoDR0KXlLXltQMudBB
|
||||
@@ -73,419 +74,438 @@ mlAZUEjsoaT9vjvjGTxl3uCm0TX5KTgtSJIt2kA1tYVjQef+/iZTHxY=
|
||||
-----END RSA PRIVATE KEY-----';
|
||||
|
||||
|
||||
/**
|
||||
* @throws ConfigException
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
if (!Config::has('ssl.public') || !Config::has('ssl.private')) {
|
||||
return;
|
||||
}
|
||||
$this->public = Config::get('ssl.public', $this->public);
|
||||
$this->private = Config::get('ssl.private', $this->private);
|
||||
$this->timeout = Config::get('ssl.timeout', 7200);
|
||||
}
|
||||
/**
|
||||
* @throws ConfigException
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
if (!Config::has('ssl.public') || !Config::has('ssl.private')) {
|
||||
return;
|
||||
}
|
||||
$this->public = Config::get('ssl.public', $this->public);
|
||||
$this->private = Config::get('ssl.private', $this->private);
|
||||
$this->timeout = Config::get('ssl.timeout', 7200);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $publicKey
|
||||
*/
|
||||
public function setPublic(string $publicKey)
|
||||
{
|
||||
$this->public = $publicKey;
|
||||
}
|
||||
/**
|
||||
* @param string $publicKey
|
||||
*/
|
||||
public function setPublic(string $publicKey)
|
||||
{
|
||||
$this->public = $publicKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $timeout
|
||||
*/
|
||||
public function setTimeout(int $timeout)
|
||||
{
|
||||
$this->timeout = $timeout;
|
||||
}
|
||||
public function setTimeout(int $timeout)
|
||||
{
|
||||
$this->timeout = $timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $timeout
|
||||
*/
|
||||
public function setKey(string $timeout)
|
||||
{
|
||||
$this->key = $timeout;
|
||||
}
|
||||
public function setKey(string $timeout)
|
||||
{
|
||||
$this->key = $timeout;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $privateKey
|
||||
*/
|
||||
public function setPrivate(string $privateKey)
|
||||
{
|
||||
$this->private = $privateKey;
|
||||
}
|
||||
/**
|
||||
* @param string $privateKey
|
||||
*/
|
||||
public function setPrivate(string $privateKey)
|
||||
{
|
||||
$this->private = $privateKey;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param int $unionId
|
||||
* @param array $headers
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function create(int $unionId, array $headers = []): array
|
||||
{
|
||||
$this->user = $unionId;
|
||||
$this->config['time'] = time();
|
||||
if (empty($headers)) {
|
||||
$headers = request()->headers->getHeaders();
|
||||
} else if ($headers instanceof HttpHeaders) {
|
||||
$headers = $headers->getHeaders();
|
||||
}
|
||||
$this->data = $headers;
|
||||
if (!isset($this->data['source'])) {
|
||||
$this->data['source'] = 'browser';
|
||||
}
|
||||
return $this->createEncrypt($unionId);
|
||||
}
|
||||
/**
|
||||
* @param int $unionId
|
||||
* @param array $headers
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function create(int $unionId, array $headers = []): array
|
||||
{
|
||||
$this->user = $unionId;
|
||||
$this->config['time'] = time();
|
||||
if (empty($headers)) {
|
||||
$headers = request()->headers->getHeaders();
|
||||
} else if ($headers instanceof HttpHeaders) {
|
||||
$headers = $headers->getHeaders();
|
||||
}
|
||||
$this->data = $headers;
|
||||
if (!isset($this->data['source'])) {
|
||||
$this->data['source'] = 'browser';
|
||||
}
|
||||
return $this->createEncrypt($unionId);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param $unionId
|
||||
* @return array
|
||||
* @throws Exception
|
||||
* 对相关信息进行加密
|
||||
*/
|
||||
private function createEncrypt($unionId): array
|
||||
{
|
||||
$caches = $this->clear($unionId);
|
||||
$param = $this->assembly(array_merge($this->config, [
|
||||
'user' => $unionId,
|
||||
'token' => $this->token($unionId, [
|
||||
'device' => Str::rand(128),
|
||||
], $this->config['time']),
|
||||
]), TRUE);
|
||||
$refresh = array_intersect_key($param, $this->config);
|
||||
/**
|
||||
* @param $unionId
|
||||
* @return array
|
||||
* @throws Exception
|
||||
* 对相关信息进行加密
|
||||
*/
|
||||
private function createEncrypt($unionId): array
|
||||
{
|
||||
$caches = $this->clear($unionId);
|
||||
$param = $this->assembly(array_merge($this->config, [
|
||||
'user' => $unionId,
|
||||
'token' => $this->token($unionId, [
|
||||
'device' => Str::rand(128),
|
||||
], $this->config['time']),
|
||||
]), TRUE);
|
||||
$refresh = array_intersect_key($param, $this->config);
|
||||
|
||||
$params['user'] = $this->user;
|
||||
$params['token'] = $refresh['token'];
|
||||
$json = json_encode($params, JSON_NUMERIC_CHECK | JSON_UNESCAPED_UNICODE);
|
||||
$params['user'] = $this->user;
|
||||
$params['token'] = $refresh['token'];
|
||||
$json = json_encode($params, JSON_NUMERIC_CHECK | JSON_UNESCAPED_UNICODE);
|
||||
|
||||
openssl_private_encrypt($json, $encode, $this->private);
|
||||
$refresh['refresh'] = base64_encode($encode);
|
||||
$this->setRefresh($refresh['refresh']);
|
||||
openssl_private_encrypt($json, $encode, $this->private);
|
||||
$refresh['refresh'] = base64_encode($encode);
|
||||
$this->setRefresh($refresh['refresh']);
|
||||
|
||||
$redis = $this->getRedis();
|
||||
foreach ($caches as $cache) {
|
||||
$redis->del($cache);
|
||||
}
|
||||
return $refresh;
|
||||
}
|
||||
$redis = $this->getRedis();
|
||||
foreach ($caches as $cache) {
|
||||
$redis->del($cache);
|
||||
}
|
||||
return $refresh;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param bool $update
|
||||
* @param array $param
|
||||
* @return array
|
||||
* @throws
|
||||
*/
|
||||
private function assembly(array $param, bool $update = FALSE): array
|
||||
{
|
||||
if (isset($param['sign'])) {
|
||||
unset($param['sign']);
|
||||
}
|
||||
$param = $this->initialize($param);
|
||||
asort($param, SORT_STRING);
|
||||
$_tmp = [];
|
||||
foreach ($param as $key => $val) {
|
||||
$_tmp[] = trim($key) . '=>' . trim((string)$val);
|
||||
}
|
||||
$param['sign'] = md5(implode(':', $_tmp));
|
||||
if ($update) {
|
||||
$this->setCache($param);
|
||||
}
|
||||
return $param;
|
||||
}
|
||||
/**
|
||||
* @param bool $update
|
||||
* @param array $param
|
||||
* @return array
|
||||
* @throws
|
||||
*/
|
||||
private function assembly(array $param, bool $update = FALSE): array
|
||||
{
|
||||
if (isset($param['sign'])) {
|
||||
unset($param['sign']);
|
||||
}
|
||||
$param = $this->initialize($param);
|
||||
asort($param, SORT_STRING);
|
||||
$_tmp = [];
|
||||
foreach ($param as $key => $val) {
|
||||
$_tmp[] = trim($key) . '=>' . trim((string)$val);
|
||||
}
|
||||
$param['sign'] = md5(implode(':', $_tmp));
|
||||
if ($update) {
|
||||
$this->setCache($param);
|
||||
}
|
||||
return $param;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $headers
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function refresh(array $headers = []): array
|
||||
{
|
||||
$this->data = $headers;
|
||||
if (!openssl_public_decrypt(base64_decode($headers['refresh']), $data, $this->public)) {
|
||||
throw new AuthException('信息解码失败.');
|
||||
}
|
||||
/**
|
||||
* @param array $headers
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function refresh(array $headers = []): array
|
||||
{
|
||||
$this->data = $headers;
|
||||
if (!openssl_public_decrypt(base64_decode($headers['refresh']), $data, $this->public)) {
|
||||
throw new AuthException('信息解码失败.');
|
||||
}
|
||||
|
||||
$this->user = $data['user'];
|
||||
$this->user = $data['user'];
|
||||
|
||||
if (!$this->getRedis()->exists('refresh:' . $this->user)) {
|
||||
throw new AuthException('refresh data error.');
|
||||
}
|
||||
if (!$this->getRedis()->exists('refresh:' . $this->user)) {
|
||||
throw new AuthException('refresh data error.');
|
||||
}
|
||||
|
||||
$this->getRedis()->del('refresh:' . $this->user);
|
||||
$this->getRedis()->del('refresh:' . $this->user);
|
||||
|
||||
return $this->create($this->user, $headers);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $headers
|
||||
* @return mixed
|
||||
* @throws AuthException
|
||||
*/
|
||||
public function getTokenUser(array $headers = []): int
|
||||
{
|
||||
$this->data = $headers;
|
||||
if (!openssl_public_decrypt(base64_decode($headers['refresh']), $data, $this->public)) {
|
||||
throw new AuthException('信息解码失败.');
|
||||
}
|
||||
|
||||
$data = Json::decode($data, true);
|
||||
|
||||
return (int)$data['user'];
|
||||
}
|
||||
|
||||
return $this->create($this->user, $headers);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $param
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function initialize(array $param): array
|
||||
{
|
||||
$_param = [
|
||||
'version' => '1',
|
||||
'source' => $this->getSource(),
|
||||
];
|
||||
if (!isset($param['device'])) {
|
||||
$param['device'] = Str::rand(128);
|
||||
}
|
||||
return array_merge($_param, $param);
|
||||
}
|
||||
private function initialize(array $param): array
|
||||
{
|
||||
$_param = [
|
||||
'version' => '1',
|
||||
'source' => $this->getSource(),
|
||||
];
|
||||
if (!isset($param['device'])) {
|
||||
$param['device'] = Str::rand(128);
|
||||
}
|
||||
return array_merge($_param, $param);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @throws Exception
|
||||
*/
|
||||
private function setCache(array $data)
|
||||
{
|
||||
$redis = $this->getRedis();
|
||||
$redis->hMset($this->authKey($this->getSource(), $data['token']), $data);
|
||||
$redis->expire($this->authKey($this->getSource(), $data['token']), $this->timeout);
|
||||
}
|
||||
/**
|
||||
* @param array $data
|
||||
* @throws Exception
|
||||
*/
|
||||
private function setCache(array $data)
|
||||
{
|
||||
$redis = $this->getRedis();
|
||||
$redis->hMset($this->authKey($this->getSource(), $data['token']), $data);
|
||||
$redis->expire($this->authKey($this->getSource(), $data['token']), $this->timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $refresh
|
||||
* @throws Exception
|
||||
*/
|
||||
private function setRefresh(string $refresh)
|
||||
{
|
||||
$redis = $this->getRedis();
|
||||
/**
|
||||
* @param string $refresh
|
||||
* @throws Exception
|
||||
*/
|
||||
private function setRefresh(string $refresh)
|
||||
{
|
||||
$redis = $this->getRedis();
|
||||
|
||||
$redis->set('refresh:' . $this->user, $refresh);
|
||||
$redis->expire('refresh:' . $this->user, $this->timeout);
|
||||
}
|
||||
$redis->set('refresh:' . $this->user, $refresh);
|
||||
$redis->expire('refresh:' . $this->user, $this->timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $_source
|
||||
* @param string $token
|
||||
*
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
private function authKey(string $_source, string $token): string
|
||||
{
|
||||
$source = $this->getSource();
|
||||
if (!empty($_source)) $source = $_source;
|
||||
/**
|
||||
* @param string $_source
|
||||
* @param string $token
|
||||
*
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
private function authKey(string $_source, string $token): string
|
||||
{
|
||||
$source = $this->getSource();
|
||||
if (!empty($_source)) $source = $_source;
|
||||
|
||||
return 'Tmp_Token:' . strtoupper($source) . ':' . $token;
|
||||
}
|
||||
return 'Tmp_Token:' . strtoupper($source) . ':' . $token;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSource(): string
|
||||
{
|
||||
return $this->data['source'] ?? 'browser';
|
||||
}
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function getSource(): string
|
||||
{
|
||||
return $this->data['source'] ?? 'browser';
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $user
|
||||
* @param array $param
|
||||
* @param null $requestTime
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function token(int $user, array $param = [], $requestTime = NULL): string
|
||||
{
|
||||
$str = '';
|
||||
/**
|
||||
* @param int $user
|
||||
* @param array $param
|
||||
* @param null $requestTime
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function token(int $user, array $param = [], $requestTime = NULL): string
|
||||
{
|
||||
$str = '';
|
||||
|
||||
$user = (string)$user;
|
||||
$_user = str_split(md5($user . md5($user)));
|
||||
ksort($_user);
|
||||
foreach ($_user as $key => $val) {
|
||||
$str .= md5(sha1($key . $val . $this->key));
|
||||
}
|
||||
foreach ($param as $key => $val) {
|
||||
$str .= md5($str . sha1($key . md5($val)));
|
||||
}
|
||||
$str .= sha1(base64_encode((string)$requestTime));
|
||||
return $this->preg(md5($str . $user));
|
||||
}
|
||||
$user = (string)$user;
|
||||
$_user = str_split(md5($user . md5($user)));
|
||||
ksort($_user);
|
||||
foreach ($_user as $key => $val) {
|
||||
$str .= md5(sha1($key . $val . $this->key));
|
||||
}
|
||||
foreach ($param as $key => $val) {
|
||||
$str .= md5($str . sha1($key . md5($val)));
|
||||
}
|
||||
$str .= sha1(base64_encode((string)$requestTime));
|
||||
return $this->preg(md5($str . $user));
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $str
|
||||
*
|
||||
* @return array|string|null 将字符串替换成指定格式
|
||||
*/
|
||||
private function preg(string $str): null|array|string
|
||||
{
|
||||
return preg_replace('/(\w{10})(\w{3})(\w{4})(\w{9})(\w{6})/', '$1-$2-$3-$4-$5', $str);
|
||||
}
|
||||
/**
|
||||
* @param string $str
|
||||
*
|
||||
* @return array|string|null 将字符串替换成指定格式
|
||||
*/
|
||||
private function preg(string $str): null|array|string
|
||||
{
|
||||
return preg_replace('/(\w{10})(\w{3})(\w{4})(\w{9})(\w{6})/', '$1-$2-$3-$4-$5', $str);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $user
|
||||
* @return string[]
|
||||
* @throws Exception
|
||||
*/
|
||||
public function clear(int $user): array
|
||||
{
|
||||
$this->user = $user;
|
||||
$redis = $this->getRedis();
|
||||
if (is_bool($refresh = $redis->get('refresh:' . $this->user))) {
|
||||
return [];
|
||||
};
|
||||
openssl_public_decrypt(base64_decode($refresh), $info, $this->public);
|
||||
/**
|
||||
* @param int $user
|
||||
* @return string[]
|
||||
* @throws Exception
|
||||
*/
|
||||
public function clear(int $user): array
|
||||
{
|
||||
$this->user = $user;
|
||||
$redis = $this->getRedis();
|
||||
if (is_bool($refresh = $redis->get('refresh:' . $this->user))) {
|
||||
return [];
|
||||
};
|
||||
openssl_public_decrypt(base64_decode($refresh), $info, $this->public);
|
||||
|
||||
$_tmp = [];
|
||||
if (!empty($info) && $json = json_decode($info, true)) {
|
||||
if (!isset($json['token'])) {
|
||||
return [];
|
||||
}
|
||||
foreach ($this->source as $value) {
|
||||
$_tmp[] = $this->authKey($value, $json['token']);
|
||||
}
|
||||
}
|
||||
return $_tmp;
|
||||
}
|
||||
$_tmp = [];
|
||||
if (!empty($info) && $json = json_decode($info, true)) {
|
||||
if (!isset($json['token'])) {
|
||||
return [];
|
||||
}
|
||||
foreach ($this->source as $value) {
|
||||
$_tmp[] = $this->authKey($value, $json['token']);
|
||||
}
|
||||
}
|
||||
return $_tmp;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $data
|
||||
* @param int $user
|
||||
* @return bool
|
||||
* @throws AuthException|Exception
|
||||
*/
|
||||
public function check(array $data, int $user): bool
|
||||
{
|
||||
$this->data = $data;
|
||||
$this->user = $user;
|
||||
/**
|
||||
* @param array $data
|
||||
* @param int $user
|
||||
* @return bool
|
||||
* @throws AuthException|Exception
|
||||
*/
|
||||
public function check(array $data, int $user): bool
|
||||
{
|
||||
$this->data = $data;
|
||||
$this->user = $user;
|
||||
|
||||
if (empty($this->user)) return FALSE;
|
||||
$cache = $this->getUserModel();
|
||||
if (empty($cache)) {
|
||||
return FALSE;
|
||||
}
|
||||
if (empty($this->user)) return FALSE;
|
||||
$cache = $this->getUserModel();
|
||||
if (empty($cache)) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$merge = $this->assembly(array_merge($cache, [
|
||||
'token' => $data['token'],
|
||||
]));
|
||||
$check = array_diff_assoc($this->initialize($cache), $merge);
|
||||
return !((bool)count($check));
|
||||
}
|
||||
$merge = $this->assembly(array_merge($cache, [
|
||||
'token' => $data['token'],
|
||||
]));
|
||||
$check = array_diff_assoc($this->initialize($cache), $merge);
|
||||
return !((bool)count($check));
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
* @throws
|
||||
*/
|
||||
public function getCurrentOnlineUser(): int
|
||||
{
|
||||
$this->data = request()->headers->getHeaders();
|
||||
/**
|
||||
* @return mixed
|
||||
* @throws
|
||||
*/
|
||||
public function getCurrentOnlineUser(): int
|
||||
{
|
||||
$this->data = request()->headers->getHeaders();
|
||||
|
||||
return $this->loadByCache();
|
||||
}
|
||||
return $this->loadByCache();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string $token
|
||||
* @param string $source
|
||||
* @return mixed
|
||||
* @throws AuthException
|
||||
*/
|
||||
public function getOnlineUserByToken(string $token, string $source = 'BROWSER'): int
|
||||
{
|
||||
$this->data['token'] = $token;
|
||||
$this->data['source'] = $source;
|
||||
/**
|
||||
* @param string $token
|
||||
* @param string $source
|
||||
* @return mixed
|
||||
* @throws AuthException
|
||||
*/
|
||||
public function getOnlineUserByToken(string $token, string $source = 'BROWSER'): int
|
||||
{
|
||||
$this->data['token'] = $token;
|
||||
$this->data['source'] = $source;
|
||||
|
||||
return $this->loadByCache();
|
||||
}
|
||||
return $this->loadByCache();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return int
|
||||
* @throws AuthException
|
||||
* @throws Exception
|
||||
*/
|
||||
private function loadByCache(): int
|
||||
{
|
||||
$model = $this->getUserModel();
|
||||
if (empty($model)) {
|
||||
return (int)$this->addError('授权信息已过期!');
|
||||
}
|
||||
if (!isset($model['user'])) {
|
||||
return (int)$this->addError('授权信息错误!');
|
||||
}
|
||||
if (!$this->check($this->data, (int)$model['user'])) {
|
||||
return (int)$this->addError('授权信息不合法!');
|
||||
}
|
||||
/**
|
||||
* @return int
|
||||
* @throws AuthException
|
||||
* @throws Exception
|
||||
*/
|
||||
private function loadByCache(): int
|
||||
{
|
||||
$model = $this->getUserModel();
|
||||
if (empty($model)) {
|
||||
return (int)$this->addError('授权信息已过期!');
|
||||
}
|
||||
if (!isset($model['user'])) {
|
||||
return (int)$this->addError('授权信息错误!');
|
||||
}
|
||||
if (!$this->check($this->data, (int)$model['user'])) {
|
||||
return (int)$this->addError('授权信息不合法!');
|
||||
}
|
||||
|
||||
$this->expireRefresh();
|
||||
$this->expireRefresh();
|
||||
|
||||
return (int)$model['user'];
|
||||
}
|
||||
return (int)$model['user'];
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param array $header
|
||||
* @return mixed
|
||||
* @throws AuthException
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function checkAuth(array $header = []): mixed
|
||||
{
|
||||
$instance = Snowflake::app()->getJwt();
|
||||
if (empty($header)) {
|
||||
$header = request()->headers->getHeaders();
|
||||
}
|
||||
/**
|
||||
* @param array $header
|
||||
* @return mixed
|
||||
* @throws AuthException
|
||||
* @throws Exception
|
||||
*/
|
||||
public static function checkAuth(array $header = []): mixed
|
||||
{
|
||||
$instance = Snowflake::app()->getJwt();
|
||||
if (empty($header)) {
|
||||
$header = request()->headers->getHeaders();
|
||||
}
|
||||
|
||||
$instance->data = $header;
|
||||
$model = $instance->getUserModel();
|
||||
if (empty($model) || !isset($model['user'])) {
|
||||
return false;
|
||||
}
|
||||
$instance->data = $header;
|
||||
$model = $instance->getUserModel();
|
||||
if (empty($model) || !isset($model['user'])) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$instance->check($header, (int)$model['user'])) {
|
||||
return false;
|
||||
}
|
||||
$instance->expireRefresh();
|
||||
return $model['user'];
|
||||
}
|
||||
if (!$instance->check($header, (int)$model['user'])) {
|
||||
return false;
|
||||
}
|
||||
$instance->expireRefresh();
|
||||
return $model['user'];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param null $token
|
||||
* @param null $source
|
||||
* @throws Exception
|
||||
*/
|
||||
public function expireRefresh($token = null, $source = null)
|
||||
{
|
||||
if (!empty($token)) {
|
||||
$this->data['token'] = $token;
|
||||
}
|
||||
if (!empty($source)) {
|
||||
$this->data['source'] = $source;
|
||||
}
|
||||
if (!isset($this->data['token'])) {
|
||||
return;
|
||||
}
|
||||
$key = $this->authKey($this->getSource(), $this->data['token']);
|
||||
$this->getRedis()->expire($key, $this->timeout);
|
||||
}
|
||||
/**
|
||||
* @param null $token
|
||||
* @param null $source
|
||||
* @throws Exception
|
||||
*/
|
||||
public function expireRefresh($token = null, $source = null)
|
||||
{
|
||||
if (!empty($token)) {
|
||||
$this->data['token'] = $token;
|
||||
}
|
||||
if (!empty($source)) {
|
||||
$this->data['source'] = $source;
|
||||
}
|
||||
if (!isset($this->data['token'])) {
|
||||
return;
|
||||
}
|
||||
$key = $this->authKey($this->getSource(), $this->data['token']);
|
||||
$this->getRedis()->expire($key, $this->timeout);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool|array
|
||||
* @throws Exception
|
||||
*/
|
||||
private function getUserModel(): bool|array
|
||||
{
|
||||
if (!isset($this->data['token'])) {
|
||||
return $this->addError('暂无访问权限!');
|
||||
}
|
||||
$key = $this->authKey($this->getSource(), $this->data['token']);
|
||||
return $this->getRedis()->hGetAll($key);
|
||||
}
|
||||
/**
|
||||
* @return bool|array
|
||||
* @throws Exception
|
||||
*/
|
||||
private function getUserModel(): bool|array
|
||||
{
|
||||
if (!isset($this->data['token'])) {
|
||||
return $this->addError('暂无访问权限!');
|
||||
}
|
||||
$key = $this->authKey($this->getSource(), $this->data['token']);
|
||||
return $this->getRedis()->hGetAll($key);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Redis|\Redis
|
||||
* @throws
|
||||
*/
|
||||
private function getRedis(): Redis|\Redis
|
||||
{
|
||||
return Snowflake::app()->getRedis();
|
||||
}
|
||||
/**
|
||||
* @return Redis|\Redis
|
||||
* @throws
|
||||
*/
|
||||
private function getRedis(): Redis|\Redis
|
||||
{
|
||||
return Snowflake::app()->getRedis();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -81,6 +81,11 @@ class ClientsPool extends Component
|
||||
{
|
||||
if (env('state') == 'exit') {
|
||||
Timer::clear($this->creates);
|
||||
foreach (static::$_connections as $channel) {
|
||||
$this->flush($channel, 0);
|
||||
$channel->close();
|
||||
}
|
||||
static::$_connections = [];
|
||||
$this->creates = -1;
|
||||
} else {
|
||||
$this->heartbeat_flush();
|
||||
@@ -131,7 +136,6 @@ class ClientsPool extends Component
|
||||
public function flush($channel, $retain_number)
|
||||
{
|
||||
$this->pop($channel, $retain_number);
|
||||
static::$_connections = [];
|
||||
}
|
||||
|
||||
|
||||
@@ -180,12 +184,16 @@ class ClientsPool extends Component
|
||||
* @param $name
|
||||
* @return Channel
|
||||
* @throws ConfigException
|
||||
* @throws Exception
|
||||
*/
|
||||
private function getChannel($name): Channel
|
||||
{
|
||||
if (!isset(static::$_connections[$name])) {
|
||||
static::$_connections[$name] = new Channel(Config::get('databases.pool.max', 10));
|
||||
}
|
||||
if (static::$_connections[$name]->errCode == SWOOLE_CHANNEL_CLOSED){
|
||||
throw new Exception('Channel is Close.');
|
||||
}
|
||||
if ($this->creates === -1) {
|
||||
$this->creates = Timer::tick(60000, [$this, 'Heartbeat_detection']);
|
||||
}
|
||||
|
||||
@@ -41,8 +41,8 @@ abstract class Process extends \Swoole\Process implements SProcess
|
||||
putenv('environmental=' . Snowflake::PROCESS);
|
||||
|
||||
fire(Event::SERVER_WORKER_START);
|
||||
if (Snowflake::getPlatform()->isLinux()) {
|
||||
swoole_set_process_name($this->getProcessName());
|
||||
if (Snowflake::getPlatform()->isLinux()) {
|
||||
name($this->pid, $this->getProcessName());
|
||||
}
|
||||
if (method_exists($this, 'before')) {
|
||||
$this->before($process);
|
||||
|
||||
@@ -46,7 +46,7 @@ abstract class BaseValidator
|
||||
* BaseValidator constructor.
|
||||
* @param array $config
|
||||
*/
|
||||
public function __construct($config = [])
|
||||
public function __construct(array $config = [])
|
||||
{
|
||||
$this->regConfig($config);
|
||||
}
|
||||
|
||||
@@ -37,14 +37,11 @@ class LengthValidator extends BaseValidator
|
||||
if (is_null($value)) {
|
||||
return $this->addError('The param :attribute is null');
|
||||
}
|
||||
switch (strtolower($this->method)) {
|
||||
case self::MAX_LENGTH:
|
||||
return $this->maxLength($value);
|
||||
case self::MIN_LENGTH:
|
||||
return $this->minLength($value);
|
||||
default:
|
||||
return $this->defaultLength($value);
|
||||
}
|
||||
return match (strtolower($this->method)) {
|
||||
self::MAX_LENGTH => $this->maxLength($value),
|
||||
self::MIN_LENGTH => $this->minLength($value),
|
||||
default => $this->defaultLength($value),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
|
||||
namespace validator;
|
||||
|
||||
|
||||
use Exception;
|
||||
|
||||
/**
|
||||
* Class RoundValidator
|
||||
* @package validator
|
||||
*/
|
||||
class RoundValidator extends BaseValidator
|
||||
{
|
||||
|
||||
|
||||
public ?int $value = null;
|
||||
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
* @throws Exception
|
||||
*/
|
||||
public function trigger(): bool
|
||||
{
|
||||
$value = $this->model->getAttribute($this->field);
|
||||
if ($value == null || round($value, $this->value) != $value) {
|
||||
return $this->addError('The param :attribute length error');
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -102,6 +102,9 @@ class Validator extends BaseValidator
|
||||
'class' => 'validator\LengthValidator',
|
||||
'method' => 'default',
|
||||
],
|
||||
'round' => [
|
||||
'class' => 'validator\RoundValidator',
|
||||
],
|
||||
];
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user