* @date 2019-11-03 14:07:35 */ declare(strict_types=1); namespace Modules\Api\Middlewares; use App\Model\UserModel; use App\Repositories\Service\QueueService; use App\Repositories\Utils\JwtRepository; use Hyperf\HttpServer\Contract\RequestInterface; use Hyperf\HttpServer\Contract\ResponseInterface as HttpResponse; use Modules\Api\Services\AuthService; use Psr\Container\ContainerInterface; use Psr\Http\Message\ResponseInterface; use Psr\Http\Message\ServerRequestInterface; use Psr\Http\Server\MiddlewareInterface; use Psr\Http\Server\RequestHandlerInterface; use Psr\SimpleCache\CacheInterface; class ApiAuthMiddleware implements MiddlewareInterface { /** * 容器实例. * * @var ContainerInterface */ protected $container = null; /** * 响应实例. * * @var HttpResponse */ protected $response = null; /** * 请求实例. * * @var RequestInterface */ protected $request = null; public function __construct(ContainerInterface $container, HttpResponse $response, RequestInterface $request) { $this->container = $container; $this->response = $response; $this->request = $request; } public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface { $authService = new AuthService(); $enToken = $authService->getHeaderToken(); $arrTokenInfo = $authService->decodeHeaderTokenInfo($enToken); $token = strval(data_get($arrTokenInfo, 'token', '')); if (empty($token)) { return json_fail('认证失败1', 403); } $jwtRepo = make(JwtRepository::class); $aud = 'app-users'; $validateResult = $jwtRepo->validateToken($token, $aud); if (!$validateResult['is_valid']) { if ($validateResult['is_expired']) { return json_fail('认证过期', 401); } return json_fail('认证失败2', 403); } else { // 验证单点. $claims = $validateResult['token_obj']->claims(); $deviceNo = $claims->get('device_no'); $deviceType = $claims->get('device_type'); $version = $claims->get('version'); $code = $claims->get('user_id'); $cacheKey = $authService->getUserDeviceCacheKey($deviceNo, $deviceType); $cache = make(CacheInterface::class); $cacheToken = $cache->has($cacheKey) ? $cache->get($cacheKey) : ''; if (empty($cacheToken) || $cacheToken !== $token) { return json_fail('认证失败3', 403); } $hDeviceNo = data_get($arrTokenInfo, 'device_no', ''); $hDeviceType = data_get($arrTokenInfo, 'device_type', ''); $hVersion = data_get($arrTokenInfo, 'version', ''); if ($hVersion != $version) { UserModel::query()->where('code', $code) ->update(['version' => $hVersion]); return json_fail(trans('common.err_failed_authorization'), 4999); } if ($hDeviceNo !== $deviceNo || $hDeviceType != $deviceType) { return json_fail('认证失败4', 403); } } return $handler->handle($request); // 洋葱管道正常执行下一个管道. } }