| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211 |
- <?php
- /**
- * 认证服务.
- *
- * @author nj <nj@gmail.com>
- * @date 2020-01-22 11:36:11
- */
- declare(strict_types=1);
- namespace Modules\Api\Services;
- use App\Constants\CommonConstant;
- use App\Exception\ApiException;
- use App\Repositories\Utils\JwtRepository;
- use Psr\SimpleCache\CacheInterface;
- class AuthService
- {
- /**
- * Jwt受众.
- *
- * @var string
- */
- private $jwtAud = 'app-users';
- /**
- * 获取存储用户设备Token的缓存Key.
- * @param string $deviceNo 设备编号
- * @param string $deviceType 设备类型
- * @return string
- */
- public function getUserDeviceCacheKey($deviceNo, $deviceType)
- {
- $cacheKey = 'user_auth_device:'. $deviceNo . '_' . $deviceType;
- 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, $deviceNo, $deviceType, $version, $fingerHash = '')
- {
- $user = [];
- $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->getUserDeviceCacheKey($deviceNo, $deviceType);
- $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 getHeaderToken()
- {
- return request()->header(CommonConstant::X_TOKEN_NAME, null);
- }
- /**
- * 加密X-TOKEN头部信息.
- * @param array $info
- * @return false|string
- */
- public function encodeHeaderTokenInfo(array $info)
- {
- $token = data_get($info, 'token', '');
- $deviceNo = data_get($info, 'device_no', '');
- $deviceType = data_get($info, 'device_type', '');
- $fingerHash = data_get($info, 'finger_hash', '');
- $arrData = [
- 'token' => $token,
- 'device_no' => $deviceNo,
- 'device_type' => $deviceType,
- 'finger_hash' => $fingerHash,
- ];
- $handshake = CommonConstant::getHandShake();
- if (!empty($handshake)) {
- $arrMap = CommonConstant::getHandSnakeKey($handshake);
- $data = hand_encrypt($arrData, $arrMap['key']);
- } else {
- $data = json_encode($arrData, JSON_UNESCAPED_UNICODE);
- }
- return $data;
- }
- /**
- * 解密头部X-Token信息.
- * @param string $enStr
- * @return array|mixed
- */
- public function decodeHeaderTokenInfo($enStr)
- {
- $data = [];
- $isValidMg = false;
- if (class_exists('\Modules\Manage\Services\AuthService')) {
- $service = make(\Modules\Manage\Services\AuthService::class);
- // 如果有效后台header,则直接不加密,进行明文通讯.
- $isValidMg = $service->checkValidMgHeaderHandShake();
- }
- // 先拿系统里当前flag.
- $handshake = CommonConstant::getHandShake();
- if (!$isValidMg) {
- if (!empty($handshake)) {
- $inputData = request()->all();
- $inputHandShake = $inputData['handshake'] ?? $handshake;
- $handshake = $inputHandShake;
- $originData = $enStr;
- $arrMap = CommonConstant::getHandSnakeKey($handshake);
- if (!is_string($originData)) {
- throw new ApiException('数据格式有误3');
- }
- try {
- $data = json_decode(hand_decrypt($originData, $arrMap['key'], ''), true);
- } catch (\Throwable $exception) {
- throw new ApiException('数据格式有误4');
- }
- } else {
- $data = [];
- if (!empty($enStr) && is_string($enStr)) {
- $data = json_decode($enStr, true);
- }
- }
- } else {
- // TODO 为了满足android在postmain里拿到解密的数据,兼容header是加密的情况.
- if (!empty($enStr)) {
- if (substr($enStr, 0, 1) == '{') {
- $data = json_decode($enStr, true);
- } else {
- $arrMap = CommonConstant::getHandSnakeKey($handshake);
- $data = json_decode(hand_decrypt($enStr, $arrMap['key'], ''), true);
- }
- }
- }
- return $data;
- }
- /**
- * 获取Token中的UserId
- * @return string
- */
- public function getUserId()
- {
- $user_id = '';
- $enToken = $this->getHeaderToken();
- $arrTokenInfo = $this->decodeHeaderTokenInfo($enToken);
- $token = strval(data_get($arrTokenInfo, 'token', ''));
- if (!empty($token)) {
- $jwtRepository = make(JwtRepository::class);
- $validateResult = $jwtRepository->validateToken($token, $this->jwtAud);
- if ($validateResult['is_valid']) {
- $user_id = $validateResult['token_obj']->claims()->get('user_id');
- }
- }
- return $user_id; //是用户邀请码,非用户id(安全设计)
- }
- /**
- * 从Token中获取用户信息.
- * @return array ['user_id', 'device_no', 'device_type']
- */
- public function getTokenUserInfo() : array
- {
- $userId = $deviceNo = $deviceType = '';
- $enToken = $this->getHeaderToken();
- $arrTokenInfo = $this->decodeHeaderTokenInfo($enToken);
- $token = strval(data_get($arrTokenInfo, 'token', ''));
- if (!empty($token)) {
- $jwtRepository = make(JwtRepository::class);
- $validateResult = $jwtRepository->validateToken($token, $this->jwtAud);
- if ($validateResult['is_valid']) {
- $userId = $validateResult['token_obj']->claims()->get('user_id');
- $deviceNo = $validateResult['token_obj']->claims()->get('device_no');
- $deviceType = $validateResult['token_obj']->claims()->get('device_type');
- }
- }
- $data = [
- 'user_id' => $userId, //是用户邀请码,非用户id(安全设计)
- 'device_no' => $deviceNo,
- 'device_type' => $deviceType,
- ];
- return $data;
- }
- }
|