Token.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162
  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): bool
  75. {
  76. // 最近有生成时直接返回
  77. $tokenArr = self::get($userID);
  78. if (!empty($tokenArr) && 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["token"] = Random::uuid(); // 使用随机字符串
  84. $tokenData["create_time"] = time();
  85. return self::init()->set($userID, json_encode($tokenData, JSON_UNESCAPED_UNICODE));
  86. }
  87. /**
  88. * 解码已加密的Token信息
  89. * @param string $token
  90. * @return array
  91. */
  92. public static function unmarshal(string $token): array
  93. {
  94. $decode = json_decode(base64_decode($token), true);
  95. $tokenArr = [];
  96. if (!empty($decode) && !empty($decode["user_id"]) && is_int($decode["user_id"]) && !empty($decode["token"]) && is_string($decode["token"])) {
  97. $tokenArr["user_id"] = $decode["user_id"];
  98. $tokenArr["token"] = $decode["token"];
  99. }
  100. return $tokenArr;
  101. }
  102. /**
  103. * 判断Token是否可用
  104. * @param int $userID 会员ID
  105. * @param string $token Token标识
  106. * @return bool
  107. */
  108. public static function check(int $userID, string $token): bool
  109. {
  110. return self::init()->check($userID, $token);
  111. }
  112. /**
  113. * 读取Token
  114. * @access public
  115. * @param int $userID 用户ID
  116. * @return array
  117. */
  118. public static function get(int $userID): array
  119. {
  120. return self::init()->get($userID);
  121. }
  122. /**
  123. * 获取加密后的Token
  124. * @access public
  125. * @param int $userID 用户ID
  126. * @return array
  127. */
  128. public static function getEncryptedToken(int $userID): string
  129. {
  130. return self::init()->getEncryptedToken($userID);
  131. }
  132. /**
  133. * 删除Token
  134. * @param int $userID 用户ID
  135. * @return bool
  136. */
  137. public static function delete(int $userID): bool
  138. {
  139. return self::init()->delete($userID);
  140. }
  141. }