Token.php 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232
  1. <?php
  2. namespace app\common\library;
  3. use think\helper\Arr;
  4. use think\helper\Str;
  5. use think\facade\Config;
  6. use InvalidArgumentException;
  7. use app\common\library\token\TokenExpirationException;
  8. /**
  9. * Token 管理类
  10. */
  11. class Token
  12. {
  13. /**
  14. * Token 实例
  15. * @var array
  16. * @uses Token 数组项
  17. */
  18. public array $instance = [];
  19. /**
  20. * token驱动类句柄
  21. * @var ?object
  22. */
  23. public ?object $handler = null;
  24. /**
  25. * 驱动类命名空间
  26. * @var string
  27. */
  28. protected string $namespace = '\\app\\common\\library\\token\\driver\\';
  29. /**
  30. * 获取驱动句柄
  31. * @param string|null $name
  32. * @return object
  33. */
  34. public function getDriver(string $name = null): object
  35. {
  36. if (!is_null($this->handler)) {
  37. return $this->handler;
  38. }
  39. $name = $name ?: $this->getDefaultDriver();
  40. if (is_null($name)) {
  41. throw new InvalidArgumentException(
  42. sprintf(
  43. 'Unable to resolve NULL driver for [%s].',
  44. static::class
  45. )
  46. );
  47. }
  48. return $this->createDriver($name);
  49. }
  50. /**
  51. * 创建驱动句柄
  52. * @param string $name
  53. * @return object
  54. */
  55. protected function createDriver(string $name): object
  56. {
  57. $type = $this->resolveType($name);
  58. $method = 'create' . Str::studly($type) . 'Driver';
  59. $params = $this->resolveParams($name);
  60. if (method_exists($this, $method)) {
  61. return $this->$method(...$params);
  62. }
  63. $class = $this->resolveClass($type);
  64. if (isset($this->instance[$type])) {
  65. return $this->instance[$type];
  66. }
  67. return new $class(...$params);
  68. }
  69. /**
  70. * 默认驱动
  71. * @return string
  72. */
  73. protected function getDefaultDriver(): string
  74. {
  75. return $this->getConfig('default');
  76. }
  77. /**
  78. * 获取驱动配置
  79. * @param string|null $name 要获取的配置项,不传递获取完整token配置
  80. * @param null $default
  81. * @return array|string
  82. */
  83. protected function getConfig(string $name = null, $default = null): array|string
  84. {
  85. if (!is_null($name)) {
  86. return Config::get('buildadmin.token.' . $name, $default);
  87. }
  88. return Config::get('buildadmin.token');
  89. }
  90. /**
  91. * 获取驱动配置参数
  92. * @param $name
  93. * @return array
  94. */
  95. protected function resolveParams($name): array
  96. {
  97. $config = $this->getStoreConfig($name);
  98. return [$config];
  99. }
  100. /**
  101. * 获取驱动类
  102. * @param string $type
  103. * @return string
  104. */
  105. protected function resolveClass(string $type): string
  106. {
  107. if ($this->namespace || str_contains($type, '\\')) {
  108. $class = str_contains($type, '\\') ? $type : $this->namespace . Str::studly($type);
  109. if (class_exists($class)) {
  110. return $class;
  111. }
  112. }
  113. throw new InvalidArgumentException("Driver [$type] not supported.");
  114. }
  115. /**
  116. * 获取驱动配置
  117. * @param string $store
  118. * @param string|null $name
  119. * @param null $default
  120. * @return array|string
  121. */
  122. protected function getStoreConfig(string $store, string $name = null, $default = null): array|string
  123. {
  124. if ($config = $this->getConfig("stores.$store")) {
  125. return Arr::get($config, $name, $default);
  126. }
  127. throw new InvalidArgumentException("Store [$store] not found.");
  128. }
  129. /**
  130. * 获取驱动类型
  131. * @param string $name
  132. * @return string
  133. */
  134. protected function resolveType(string $name): string
  135. {
  136. return $this->getStoreConfig($name, 'type', 'Mysql');
  137. }
  138. /**
  139. * 设置token
  140. * @param string $token
  141. * @param string $type
  142. * @param int $user_id
  143. * @param int|null $expire
  144. * @return bool
  145. */
  146. public function set(string $token, string $type, int $user_id, int $expire = null): bool
  147. {
  148. return $this->getDriver()->set($token, $type, $user_id, $expire);
  149. }
  150. /**
  151. * 获取token
  152. * @param string $token
  153. * @param bool $expirationException
  154. * @return array
  155. */
  156. public function get(string $token, bool $expirationException = true): array
  157. {
  158. return $this->getDriver()->get($token, $expirationException);
  159. }
  160. /**
  161. * 检查token
  162. * @param string $token
  163. * @param string $type
  164. * @param int $user_id
  165. * @param bool $expirationException
  166. * @return bool
  167. */
  168. public function check(string $token, string $type, int $user_id, bool $expirationException = true): bool
  169. {
  170. return $this->getDriver()->check($token, $type, $user_id, $expirationException);
  171. }
  172. /**
  173. * 删除token
  174. * @param string $token
  175. * @return bool
  176. */
  177. public function delete(string $token): bool
  178. {
  179. return $this->getDriver()->delete($token);
  180. }
  181. /**
  182. * 清理指定用户token
  183. * @param string $type
  184. * @param int $user_id
  185. * @return bool
  186. */
  187. public function clear(string $type, int $user_id): bool
  188. {
  189. return $this->getDriver()->clear($type, $user_id);
  190. }
  191. /**
  192. * Token过期检查
  193. * @throws TokenExpirationException
  194. */
  195. public function tokenExpirationCheck(array $token): void
  196. {
  197. if (isset($token['expire_time']) && $token['expire_time'] <= time()) {
  198. throw new TokenExpirationException();
  199. }
  200. }
  201. }