123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- <?php
- declare(strict_types=1);
- namespace App\Utils\Encrypt;
- use App\Master\Enum\RedisKeyEnum;
- use App\Utils\RedisUtil;
- use Hyperf\Config\Annotation\Value;
- use Hyperf\Coroutine\Coroutine;
- class Token
- {
- /**
- * Token 配置信息
- * @var array
- */
- #[Value("token.default")]
- protected array $config;
- private static $instances = [];
- /**
- * 协程单例模式处理
- * @return mixed|self
- */
- public static function getInstance()
- {
- $instanceName = Coroutine::id() . uniqid();//协程id&唯一id组成
- if (!isset(self::$instances[$instanceName])) {
- self::$instances[$instanceName] = new self();
- Coroutine::defer(function () use ($instanceName) {
- unset(self::$instances[$instanceName]);
- });
- }
- return self::$instances[$instanceName];
- }
- /**
- * 创建token
- * @param array $data
- * @return string
- * @throws \Exception
- */
- public function create(array $data): string
- {
- $data = array_merge($data, [
- 'iat' => time(),// 签发时间
- 'exp' => time() + $this->config['expire'],// 过期时间
- ]);
- $dataJson = json_encode($data, JSON_UNESCAPED_UNICODE);
- $token = Aes::encode($dataJson, $this->config['key']);
- // 校验唯一token,单点登录
- if ($this->config['sso'] === true) {
- $token_key = (string)key($data);
- $token_id = (string)reset($data);
- RedisUtil::getInstance(RedisKeyEnum::TOKEN_ONCE, $token_key, $token_id)->setex($token, $this->config['expire']);
- }
- return $token;
- }
- /**
- * 验证token是否有效
- * @param string $token
- * @return false|mixed
- * @throws \Exception
- */
- public function check(string $token)
- {
- //验证token
- if (!$data = Aes::decode($token, $this->config['key'])) {
- return false;
- }
- $data = json_decode($data, true);
- // 校验唯一token,单点登录
- if ($this->config['sso'] === true) {
- $token_key = (string)key($data);
- $token_id = (string)reset($data);
- if (!$userToken = RedisUtil::getInstance(RedisKeyEnum::TOKEN_ONCE, $token_key, $token_id)->get()) {
- return false;
- }
- if ($userToken != $token) {
- return false;
- }
- }
- return $data;
- }
- /**
- * 删除token
- * 仅开启单点登录时 可用
- * @param array $data 生成token时传递的参数
- * @return bool
- * @throws \Exception
- */
- public function remove(array $data)
- {
- // 单点登录 删除登录状态
- if ($this->config['sso'] === true) {
- $token_key = (string)key($data);
- $token_id = (string)reset($data);
- //验证token
- if (!RedisUtil::getInstance(RedisKeyEnum::TOKEN_ONCE, $token_key, $token_id)->del()) {
- return false;
- }
- }
- return true;
- }
- }
|