123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184 |
- <?php
- declare(strict_types=1);
- namespace App\Middleware;
- use App\Master\Enum\RedisKeyEnum;
- use App\Model\Arts\UserModel;
- use App\Service\SystemService;
- use App\Utils\AppResult;
- use App\Utils\Control\ActionUtil;
- use App\Utils\Control\AuthUser;
- use App\Utils\Encrypt\TokenUtil;
- use App\Utils\LogUtil;
- use App\Utils\RedisUtil;
- use Hyperf\Coroutine\Coroutine;
- use Hyperf\HttpServer\Contract\RequestInterface;
- use Hyperf\HttpServer\Contract\ResponseInterface as HttpResponse;
- use Hyperf\HttpServer\Router\Dispatched;
- use Psr\Container\ContainerInterface;
- use Psr\Http\Message\ResponseInterface;
- use Psr\Http\Message\ServerRequestInterface;
- use Psr\Http\Server\MiddlewareInterface;
- use Psr\Http\Server\RequestHandlerInterface;
- class ApiAgentBak implements MiddlewareInterface
- {
- // 日志模块名称
- const LOG_MODULE = 'ApiAgent-Middleware-Log';
- const LOG_ACTION = 'verifyToken';
- const PROJECT = 'Api';
- /**
- * @var ContainerInterface
- */
- protected $container;
- /**
- * @var RequestInterface
- */
- protected $request;
- /**
- * @var HttpResponse
- */
- protected $response;
- protected $action;
- 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
- {
- //日志统一写入
- LogUtil::getInstance(self::PROJECT . "/");//设置日志存入通道
- Coroutine::defer(function () {
- LogUtil::close();//协程结束后统一写入
- });
- $this->action = $action = ActionUtil::actions($request);
- // 记录用户请求参数
- LogUtil::info('请求参数', $action['controller'], $action['action'], $this->request->all());
- //接口限流,写到中间件中
- if (!RedisUtil::getInstance(RedisKeyEnum::API_REQUEST_TRAFFIC)->requestLimit("{$action['controller']}/{$action['action']}", 1, 10)) {
- LogUtil::info('请求次数过多', $action['controller'], $action['action']);
- return $this->response206();
- }
- $token = $this->request->header('Access-Token');
- if (!empty($token) && !in_array("{$action['controller']}/{$action['action']}", self::tokenWhiteList())) {
- LogUtil::info('token 验证开始', self::LOG_MODULE, self::LOG_ACTION, (string)$token);
- //设置一个假token 用于测试
- if(strpos($token,'testuid_') !== false){
- $user_id = intval(substr($token,8));
- } else {
- // 校验token
- if (!$user_id = $this->checkToken($token)){
- return $this->response400();
- }
- }
- // 查询并记录用户信息
- $user = (new UserModel())->authUserInfo((int)$user_id);
- if (!$user) {
- //防止在缓存后操作得用户登录重试,清除缓存
- $system = new SystemService();
- $system->flushCache((int)$user_id);
- LogUtil::warning('账号不存在', self::LOG_MODULE, self::LOG_ACTION, ['user_id', $user_id]);
- return $this->response400();
- }
- LogUtil::info('用户编号', $action['controller'], $action['action'], $user_id);
- AuthUser::getInstance()->set(json_decode(json_encode($user), true));
- }
- return $handler->handle($request);
- }
- /**
- * 校验token
- *
- * @param string $token
- * @return false
- */
- public function checkToken(string $token)
- {
- $checkToken = TokenUtil::verifyToken($token);
- if (!$checkToken) {
- LogUtil::warning('token 验证失败', self::LOG_MODULE, self::LOG_ACTION, $checkToken);
- return false;
- }
- //签发时间大于当前服务器时间验证失败
- if (!isset($checkToken['iat']) || $checkToken['iat'] > time()) {
- LogUtil::warning('token 未生效', self::LOG_MODULE, self::LOG_ACTION, $checkToken);
- return false;
- }
- //过期时间小于当前服务器时间验证失败
- if (!isset($checkToken['exp']) || $checkToken['exp'] < time()) {
- LogUtil::warning('token 已失效', self::LOG_MODULE, self::LOG_ACTION, $checkToken);
- return false;
- }
- //验证参数信息
- if (empty($checkToken['data']['user_id'])) {
- LogUtil::warning('token 参数不全', self::LOG_MODULE, self::LOG_ACTION, $checkToken);
- return false;
- }
- return $checkToken['data']['user_id'];
- }
- /**
- * 令牌失效
- *
- * @param string $message
- * @param $result
- * @return ResponseInterface
- */
- private function response400(string $message = '令牌失效,请稍后重试!', $result = null): ResponseInterface
- {
- // 记录令牌校验
- $action = $this->action;
- LogUtil::info($message, $action['controller'], $action['action'], $result);
- return AppResult::response400($message, $result);
- }
- /**
- * 请求频繁
- *
- * @param string $message
- * @param $result
- * @return ResponseInterface
- */
- private function response206(string $message = '当前访问人数过多,请稍后再试!', $result = null): ResponseInterface
- {
- // 记录令牌校验
- $action = $this->action;
- LogUtil::info($message, $action['controller'], $action['action'], $result);
- return AppResult::response206($message, $result);
- }
- /**
- * token校验黑名单
- * @return string[]
- */
- public function tokenWhiteList(): array
- {
- return [
- 'v1/Common/PassportController/login',
- 'v1/Common/PassportController/wxLogin',
- ];
- }
- }
|