* @date 2020-01-22 11:36:11 */ declare(strict_types=1); namespace Modules\Web\Services; use App\Constants\CommonConstant; use App\Exception\ApiException; use App\Repositories\Utils\JwtRepository; use Psr\SimpleCache\CacheInterface; use App\Repositories\UserRepository; class AuthService { /** * Jwt受众. * * @var string */ private $jwtAud = 'pc-users'; /** * 获取存储用户设备Token的缓存Key. * @param string $deviceNo 设备编号 * @param string $deviceType 设备类型 * @return string */ public function getUserCacheKey($userCode) { $cacheKey = 'pc_auth_user:'. $userCode; return $cacheKey; } /** * 创建单点Jwt. * @param string $userId 用户ID(邀请码) * @param string $deviceNo 设备编号 * @param string $deviceType 设备类型 * @param string $version 版本 * @param string $fingerHash 指纹 * @return array * @throws \Psr\SimpleCache\InvalidArgumentException */ public function createSingleJwt($userId) { $user = []; $deviceNo = $deviceType = $version = $fingerHash = ''; $user['user_id'] = $userId; $user['device_no'] = $deviceNo; $user['device_type'] = $deviceType; $user['version'] = $version; $user['finger_hash'] = $fingerHash; $jwtRepository = make(JwtRepository::class); $tokenInfo = $jwtRepository->createAppJwt($user, $this->jwtAud); $token = $tokenInfo['token']; $cacheKey = $this->getUserCacheKey($userId); $cache = make(CacheInterface::class); // $cacheToken = $cache->has($cacheKey) ? $cache->get($cacheKey) : ''; // if (!empty($cacheToken)) { // $cache->delete($cacheKey); // } $cache->set($cacheKey, $token, config('jwt.ttl') * 60); return $tokenInfo; } /** * 获取头部Token. * @return mixed */ public function getToken() { $token = request()->input('token', null); return urldecode(trim($token)); } /** * 解密token * @param $token * @return array */ public function decodeTokenInfo($token) { $arrInfo = []; if (!empty($token)) { $jwtRepository = make(JwtRepository::class); $validateResult = $jwtRepository->validateToken($token, $this->jwtAud); if ($validateResult['is_valid']) { $arrInfo = $validateResult['token_obj']->claims()->all(); } } return $arrInfo; } /** * 获取Token中的UserId * @return string */ public function getUserId() { $user_id = ''; $token = $this->getToken(); if (!empty($token)) { $tokenInfo = $this->decodeTokenInfo($token); if (isset($tokenInfo['user_id'])) { $user_id = $tokenInfo['user_id']; } } return $user_id; //是用户邀请码,非用户id(安全设计) } /** * 从Token中获取用户信息. * @return array ['user_id', 'device_no', 'device_type'] */ public function getTokenUserInfo() : array { $userId = $deviceNo = $deviceType = ''; $token = $this->getToken(); if (!empty($token)) { $tokenInfo = $this->decodeTokenInfo($token); $jwtRepository = make(JwtRepository::class); $validateResult = $jwtRepository->validateToken($token, $this->jwtAud); if ($validateResult['is_valid']) { $userId = data_get($tokenInfo, 'user_id', ''); $deviceNo = data_get($tokenInfo, 'device_no', ''); $deviceType = data_get($tokenInfo, 'device_type', ''); } } $data = [ 'user_id' => $userId, //是用户邀请码,非用户id(安全设计) 'device_no' => $deviceNo, 'device_type' => $deviceType, ]; return $data; } /** * @param $userCode * @return mixed * @throws \Psr\SimpleCache\InvalidArgumentException */ public function checkValid($userCode) { $requestToken = $this->getToken(); $cacheKey = $this->getUserCacheKey($userCode); $cacheRepo = make(CacheInterface::class); $token = $cacheRepo->get($cacheKey, ''); if (empty($token) || empty($requestToken)) { return false; } if ($requestToken !== $token) { return false; } $userDetail = make(UserRepository::class)->getUserInfoFromCache($userCode); $appCacheKey = $this->getUserDeviceCacheKey($userDetail['device_no'], $userDetail['device_type']); $appToken = $cacheRepo->get($appCacheKey, []); if (empty($appToken)) { // 说明用户没用APP return false; } return $userDetail; } /** * 获取存储用户设备Token的缓存Key. * @param string $deviceNo 设备编号 * @param string $deviceType 设备类型 * @return string */ public function getUserDeviceCacheKey($deviceNo, $deviceType) { $cacheKey = 'user_auth_device:'. $deviceNo . '_' . $deviceType; return $cacheKey; } }