Token.php 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. <?php
  2. namespace app\common\library;
  3. use app\common\library\token\Driver;
  4. use fast\Random;
  5. use think\App;
  6. use think\Config;
  7. use think\Log;
  8. /**
  9. * Token操作类
  10. */
  11. class Token
  12. {
  13. /**
  14. * @var array Token的实例
  15. */
  16. public static array $instance = [];
  17. /**
  18. * @var Driver 操作句柄
  19. */
  20. public static $handler;
  21. /**
  22. * 连接Token驱动
  23. * @access public
  24. * @param array $options 配置数组
  25. * @param bool|string $name Token连接标识 true 强制重新连接
  26. * @return Driver
  27. */
  28. public static function connect(array $options = [], $name = false): Driver
  29. {
  30. $type = !empty($options['type']) ? $options['type'] : 'File';
  31. if (false === $name) {
  32. $name = md5(serialize($options));
  33. }
  34. if (true === $name || !isset(self::$instance[$name])) {
  35. $class = false === strpos($type, '\\') ?
  36. '\\app\\common\\library\\token\\driver\\' . ucwords($type) :
  37. $type;
  38. // 记录初始化信息
  39. App::$debug && Log::record('[ TOKEN ] INIT ' . $type, 'info');
  40. if (true === $name) {
  41. return new $class($options);
  42. }
  43. self::$instance[$name] = new $class($options);
  44. }
  45. return self::$instance[$name];
  46. }
  47. /**
  48. * 自动初始化Token
  49. * @access public
  50. * @param array $options 配置数组
  51. * @return Driver
  52. */
  53. public static function init(array $options = []): Driver
  54. {
  55. if (is_null(self::$handler)) {
  56. if (empty($options) && 'complex' == Config::get('token.type')) {
  57. $default = Config::get('token.default');
  58. // 获取默认Token配置,并连接
  59. $options = Config::get('token.' . $default['type']) ?: $default;
  60. } elseif (empty($options)) {
  61. $options = Config::get('token');
  62. }
  63. self::$handler = self::connect($options);
  64. }
  65. return self::$handler;
  66. }
  67. /**
  68. * 写入Token
  69. * @access public
  70. * @param int $userID 用户ID
  71. * @param string $address 凭证
  72. * @return bool
  73. */
  74. public static function marshal(int $userID, string $address): bool
  75. {
  76. // 最近有生成时直接返回
  77. $tokenArr = self::get($userID);
  78. if (!empty($tokenArr) && isset($tokenArr['address']) && $tokenArr['address'] == $address && isset($tokenArr['create_time']) && $tokenArr['create_time'] + Config::get('token.reuse_duration') > time()) {
  79. return true;
  80. }
  81. // 不存在或超过一定时间则重新生成
  82. $tokenData["user_id"] = $userID;
  83. $tokenData["address"] = $address;
  84. $tokenData["token"] = Random::uuid(); // 使用随机字符串
  85. $tokenData["create_time"] = time();
  86. return self::init()->set($userID, json_encode($tokenData, JSON_UNESCAPED_UNICODE));
  87. }
  88. /**
  89. * 解码已加密的Token信息
  90. * @param string $token
  91. * @return array
  92. */
  93. public static function unmarshal(string $token): array
  94. {
  95. $decode = json_decode(base64_decode($token), true);
  96. $tokenArr = [];
  97. if (!empty($decode) && !empty($decode["user_id"]) && is_int($decode["user_id"]) && !empty($decode["token"]) && is_string($decode["token"]) && !empty($decode["address"]) && is_string($decode["address"])) {
  98. $tokenArr["user_id"] = $decode["user_id"];
  99. $tokenArr["address"] = $decode["address"];
  100. $tokenArr["token"] = $decode["token"];
  101. }
  102. return $tokenArr;
  103. }
  104. /**
  105. * 判断Token是否可用
  106. * @param int $userID 会员ID
  107. * @param string $token Token标识
  108. * @return bool
  109. */
  110. public static function check(int $userID, string $token): bool
  111. {
  112. return self::init()->check($userID, $token);
  113. }
  114. /**
  115. * 读取Token
  116. * @access public
  117. * @param int $userID 用户ID
  118. * @return array
  119. */
  120. public static function get(int $userID): array
  121. {
  122. return self::init()->get($userID);
  123. }
  124. /**
  125. * 获取加密后的Token
  126. * @access public
  127. * @param int $userID 用户ID
  128. * @return array
  129. */
  130. public static function getEncryptedToken(int $userID): string
  131. {
  132. return self::init()->getEncryptedToken($userID);
  133. }
  134. /**
  135. * 删除Token
  136. * @param int $userID 用户ID
  137. * @return bool
  138. */
  139. public static function delete(int $userID): bool
  140. {
  141. return self::init()->delete($userID);
  142. }
  143. }