AuthService.php 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. <?php
  2. /**
  3. * 认证服务.
  4. *
  5. * @author nj <nj@gmail.com>
  6. * @date 2020-01-22 11:36:11
  7. */
  8. declare(strict_types=1);
  9. namespace Modules\Web\Services;
  10. use App\Constants\CommonConstant;
  11. use App\Exception\ApiException;
  12. use App\Repositories\Utils\JwtRepository;
  13. use Psr\SimpleCache\CacheInterface;
  14. use App\Repositories\UserRepository;
  15. class AuthService
  16. {
  17. /**
  18. * Jwt受众.
  19. *
  20. * @var string
  21. */
  22. private $jwtAud = 'pc-users';
  23. /**
  24. * 获取存储用户设备Token的缓存Key.
  25. * @param string $deviceNo 设备编号
  26. * @param string $deviceType 设备类型
  27. * @return string
  28. */
  29. public function getUserCacheKey($userCode)
  30. {
  31. $cacheKey = 'pc_auth_user:'. $userCode;
  32. return $cacheKey;
  33. }
  34. /**
  35. * 创建单点Jwt.
  36. * @param string $userId 用户ID(邀请码)
  37. * @param string $deviceNo 设备编号
  38. * @param string $deviceType 设备类型
  39. * @param string $version 版本
  40. * @param string $fingerHash 指纹
  41. * @return array
  42. * @throws \Psr\SimpleCache\InvalidArgumentException
  43. */
  44. public function createSingleJwt($userId)
  45. {
  46. $user = [];
  47. $deviceNo = $deviceType = $version = $fingerHash = '';
  48. $user['user_id'] = $userId;
  49. $user['device_no'] = $deviceNo;
  50. $user['device_type'] = $deviceType;
  51. $user['version'] = $version;
  52. $user['finger_hash'] = $fingerHash;
  53. $jwtRepository = make(JwtRepository::class);
  54. $tokenInfo = $jwtRepository->createAppJwt($user, $this->jwtAud);
  55. $token = $tokenInfo['token'];
  56. $cacheKey = $this->getUserCacheKey($userId);
  57. $cache = make(CacheInterface::class);
  58. // $cacheToken = $cache->has($cacheKey) ? $cache->get($cacheKey) : '';
  59. // if (!empty($cacheToken)) {
  60. // $cache->delete($cacheKey);
  61. // }
  62. $cache->set($cacheKey, $token, config('jwt.ttl') * 60);
  63. return $tokenInfo;
  64. }
  65. /**
  66. * 获取头部Token.
  67. * @return mixed
  68. */
  69. public function getToken()
  70. {
  71. $token = request()->input('token', null);
  72. return urldecode(trim($token));
  73. }
  74. /**
  75. * 解密token
  76. * @param $token
  77. * @return array
  78. */
  79. public function decodeTokenInfo($token)
  80. {
  81. $arrInfo = [];
  82. if (!empty($token)) {
  83. $jwtRepository = make(JwtRepository::class);
  84. $validateResult = $jwtRepository->validateToken($token, $this->jwtAud);
  85. if ($validateResult['is_valid']) {
  86. $arrInfo = $validateResult['token_obj']->claims()->all();
  87. }
  88. }
  89. return $arrInfo;
  90. }
  91. /**
  92. * 获取Token中的UserId
  93. * @return string
  94. */
  95. public function getUserId()
  96. {
  97. $user_id = '';
  98. $token = $this->getToken();
  99. if (!empty($token)) {
  100. $tokenInfo = $this->decodeTokenInfo($token);
  101. if (isset($tokenInfo['user_id'])) {
  102. $user_id = $tokenInfo['user_id'];
  103. }
  104. }
  105. return $user_id; //是用户邀请码,非用户id(安全设计)
  106. }
  107. /**
  108. * 从Token中获取用户信息.
  109. * @return array ['user_id', 'device_no', 'device_type']
  110. */
  111. public function getTokenUserInfo() : array
  112. {
  113. $userId = $deviceNo = $deviceType = '';
  114. $token = $this->getToken();
  115. if (!empty($token)) {
  116. $tokenInfo = $this->decodeTokenInfo($token);
  117. $jwtRepository = make(JwtRepository::class);
  118. $validateResult = $jwtRepository->validateToken($token, $this->jwtAud);
  119. if ($validateResult['is_valid']) {
  120. $userId = data_get($tokenInfo, 'user_id', '');
  121. $deviceNo = data_get($tokenInfo, 'device_no', '');
  122. $deviceType = data_get($tokenInfo, 'device_type', '');
  123. }
  124. }
  125. $data = [
  126. 'user_id' => $userId, //是用户邀请码,非用户id(安全设计)
  127. 'device_no' => $deviceNo,
  128. 'device_type' => $deviceType,
  129. ];
  130. return $data;
  131. }
  132. /**
  133. * @param $userCode
  134. * @return mixed
  135. * @throws \Psr\SimpleCache\InvalidArgumentException
  136. */
  137. public function checkValid($userCode)
  138. {
  139. $requestToken = $this->getToken();
  140. $cacheKey = $this->getUserCacheKey($userCode);
  141. $cacheRepo = make(CacheInterface::class);
  142. $token = $cacheRepo->get($cacheKey, '');
  143. if (empty($token) || empty($requestToken)) {
  144. return false;
  145. }
  146. if ($requestToken !== $token) {
  147. return false;
  148. }
  149. $userDetail = make(UserRepository::class)->getUserInfoFromCache($userCode);
  150. $appCacheKey = $this->getUserDeviceCacheKey($userDetail['device_no'], $userDetail['device_type']);
  151. $appToken = $cacheRepo->get($appCacheKey, []);
  152. if (empty($appToken)) {
  153. // 说明用户没用APP
  154. return false;
  155. }
  156. return $userDetail;
  157. }
  158. /**
  159. * 获取存储用户设备Token的缓存Key.
  160. * @param string $deviceNo 设备编号
  161. * @param string $deviceType 设备类型
  162. * @return string
  163. */
  164. public function getUserDeviceCacheKey($deviceNo, $deviceType)
  165. {
  166. $cacheKey = 'user_auth_device:'. $deviceNo . '_' . $deviceType;
  167. return $cacheKey;
  168. }
  169. }