Forráskód Böngészése

Merge branch 'master' of http://git.bjzxtw.org.cn:3000/zxt/admin_consumer

LiuJ 1 hete
szülő
commit
0bc9554217

+ 5 - 3
.env

@@ -38,7 +38,7 @@ DB_PREFIX=
 # REDIS_PORT=6379
 # REDIS_DB=0
 
-REDIS_HOST=192.168.1.123
+REDIS_HOST=192.168.1.234
 REDIS_AUTH=zxt_redis_dev
 REDIS_PORT=26739
 REDIS_PASSWORD=zxt_redis_dev
@@ -46,7 +46,7 @@ REDIS_DB=0
 
 
 
-AMQP_HOST=192.168.1.123
+AMQP_HOST=192.168.1.234
 AMQP_PORT=5672
 AMQP_USER=rabbitmq
 AMQP_PASSWORD=zxt_mq_dev
@@ -63,4 +63,6 @@ APPID = wx830ada852dd1707f
 APP_SECRET = 09d1ac9287cb6f3c5e81aa27a6b7138e
 
 
-SENSITIVE_WORD = https://v.api.aa1.cn/api/api-mgc/index.php
+SENSITIVE_WORD = https://v.api.aa1.cn/api/api-mgc/index.php
+
+THE_HOST= adminpre.bjzxtw.org.cn

+ 182 - 1
app/Controller/LoginController.php

@@ -8,12 +8,14 @@ use App\Tools\PublicData;
 use App\Tools\Result;
 use Hyperf\Context\Context;
 use PHPStan\Type\Accessory\OversizedArrayType;
+use PHPUnit\Exception;
 use function Hyperf\Support\env;
 use Hyperf\Di\Annotation\Inject;
 use Hyperf\HttpServer\Annotation\AutoController;
 use Hyperf\Validation\Contract\ValidatorFactoryInterface;
 use \Phper666\JWTAuth\JWT;
 use App\Model\UserToken;
+use Hyperf\HttpServer\Response;
 /**
  * @AutoController()
  */
@@ -28,6 +30,14 @@ class LoginController extends AbstractController
      */
     #[Inject]
     private $userServiceClient;
+    /**
+     * @var Response
+     */
+//    private $response;
+//    public function __construct(Response $response)
+//    {
+//        $this->response = $response;
+//    }
     public function login(Jwt $jwt)
     {
 
@@ -428,12 +438,183 @@ class LoginController extends AbstractController
         }else{
             $isDel = 1;
         }
-        $jwt->logout($reqData['token']);
+        try {
+            $jwt->logout($reqData['token']);
+        }catch (\Exception $e){
+            return Result::success(['isDel' => $isDel]);
+        }
         return Result::success(['isDel' => $isDel]);
     }
 
     public function goLogin()
     {
+        // 获取请求数据并设置默认值
+        $reqData = $this->request->all();
+        // 安全过滤 Admin-Token 和 ticket
+        $adminToken = !empty($_COOKIE['Admin-Token']) ? $this->sanitizeInput($_COOKIE['Admin-Token']) : '';
+        $ticket = !empty($reqData['ticket']) ? $this->sanitizeInput($reqData['ticket']) : '';
+        $backurl = $this->sanitizeBackUrl($reqData['backurl'] ?? $_SERVER['HTTP_REFERER'] ?? '');
+
+        // 校验 THE_HOST 环境变量
+        $theHost = env("THE_HOST");
+        if (empty($theHost)) {
+            return Result::error('系统配置错误:THE_HOST 未定义');
+        }
+
+        // 如果存在 adminToken,则进行登录校验
+        if (!empty($adminToken)) {
+            try {
+                $redis = $this->container->get(\Hyperf\Redis\Redis::class);
+
+                // 如果 ticket 存在且有效,则直接跳转
+                if (!empty($ticket) && $redis->exists('ticket:' . $ticket)) {
+                    $this->redirectWithTicket($backurl, $ticket, $adminToken);
+    //                return;
+                }
+
+                // 如果 ticket 不存在或无效,则重新生成 ticket 并跳转
+                if (empty($ticket)) {
+                    $ticket = md5($adminToken);
+                }
+
+                // 跳转到目标页面
+                $this->redirectWithTicket($backurl, $ticket, $adminToken);
+    //            return;
+            } catch (\Throwable $e) {
+                // 记录异常日志
+//                \Hyperf\Logger\LoggerFactory::get('default')->error('Redis 操作失败: ' . $e->getMessage());
+                // 捕获 Redis 异常,返回错误信息
+                return Result::error('系统错误:Redis 操作失败');
+            }
+        }
+        // 如果没有 adminToken,则跳转到登录页面
+        $loginUrl = 'http://' . $theHost . '/#/login?backurl=' . urlencode($backurl);
+        return $this->response->redirect($loginUrl, 302);
+    }
+
+    /**
+     * 安全过滤输入数据
+     * @param string $input
+     * @return string
+     */
+    private function sanitizeInput(string $input): string
+    {
+        return htmlspecialchars(trim($input), ENT_QUOTES, 'UTF-8');
+    }
+
+    /**
+     * 校验并清理 backurl
+     * @param string $backurl
+     * @return string
+     */
+    private function sanitizeBackUrl(string $backurl): string
+    {
+        // 解码并去除多余字符
+        $decodedUrl = urldecode($backurl);
+        return filter_var($decodedUrl, FILTER_VALIDATE_URL) ?: '';
+    }
+
+    /**
+     * 跳转到目标页面
+     * @param string $backurl
+     * @param string $ticket
+     * @param string $adminToken
+     */
+    private function redirectWithTicket(string $backurl, string $ticket, string $adminToken)
+    {
+        $backurl = rtrim($backurl, '/');
+        $redirectUrl = $this->fun_http($backurl . '?ticket=' . $ticket . '&admintoken=' . urlencode($adminToken));
+        return $this->response->redirect($redirectUrl, 302);
+    }
+
+    /**
+     * 处理 URL
+     * @param string $url
+     * @return string
+     */
+    private function fun_http(string $url): string
+    {
+        // 确保 URL 以 http 或 https 开头
+        if (!preg_match('/^https?:\/\//i', $url)) {
+            $url = 'http://' . $url;
+        }
+        return $url;
+    }
+
+    /**
+     * 退出
+     * @return void
+     */
+    public function logout(Jwt $jwt)
+    {
+        $reqData = $this->request->all();
+        $validator = $this->validationFactory->make(
+            $reqData,
+            [
+                'backurl' => 'required',
+                'admintoken' => 'required',
+            ],
+            [
+                'backurl.required' => 'backurl不能为空',
+                'admintoken.required' => 'admintoken不能为空',
+            ]
+        );
+        if ($validator->fails()) {
+            $errorMessage = $validator->errors()->first();
+            return Result::error($errorMessage);
+        }
+        $redis = $this->container->get(\Hyperf\Redis\Redis::class);
+        $ticket = md5($reqData['admintoken']);
+        $isDel = 0;
+        if ($redis->exists('ticket:' . $ticket)) {
+            $res = $redis->del('ticket:' . $ticket);
+            if (!!$res && $res == 1) $isDel = 1;
+        }else{
+            $isDel = 1;
+        }
+        setcookie("Admin-Token", "", time(), "/");
+        try {
+            $jwt->logout($reqData['admintoken']);
 
+        }catch (\Exception $e){
+            $backurl = $this->fun_http($reqData['backurl']);
+            return $this->response->redirect($backurl, 302);
+        }
+        $backurl = $this->fun_http($reqData['backurl']);
+        return $this->response->redirect($backurl, 302);
     }
+
+    /**
+     * 登录回调
+     * @return void
+     */
+    public function backlogin()
+    {
+        $reqData = $this->request->all();
+        $validator = $this->validationFactory->make(
+            $reqData,
+            [
+                'backurl' => 'required',
+                'token' => 'required',
+            ],
+            [
+                'backurl.required' => 'backurl不能为空',
+                'token.required' => 'token不能为空',
+            ]
+        );
+        if ($validator->fails()) {
+            $errorMessage = $validator->errors()->first();
+            return Result::error($errorMessage);
+        }
+        $redis = $this->container->get(\Hyperf\Redis\Redis::class);
+        $ticket = md5($reqData['token']);
+        $res = $redis->set('ticket:' . $ticket, $reqData['token'],  3600*24);
+        if($res && !empty($ticket)){
+            $url = $reqData['backurl'] . '/?ticket=' . $ticket . '&admintoken=' . urlencode($reqData['token']);
+            $url = $this->fun_http($url);
+            return $this->response->redirect($url, 302);
+        }
+    }
+
+
 }

+ 5 - 21
app/Controller/NewsController.php

@@ -964,22 +964,6 @@ class NewsController extends AbstractController
     public function getJobCompany()
     {
         $requireData = $this->request->all();
-        if (!empty($requireData)) {
-            $validator = $this->validationFactory->make(
-                $requireData,
-                [
-                    'job_id' => 'integer|required',
-                ],
-                [
-                    'job_id.integer' => '职位id必须是整数',
-                    'job_id.required' => '职位id不能为空',
-                ]
-            );
-            if ($validator->fails()) {
-                $errorMessage = $validator->errors()->first();
-                return Result::error($errorMessage);
-            }
-        }
         $requireData['website_id'] = Context::get("SiteId");
         $requireData['user_id'] = Context::get("UserId");
         // return Result::success($requireData);
@@ -1005,8 +989,8 @@ class NewsController extends AbstractController
                 'company_hy_id' => 'required|integer',
                 'company_size' => 'required|integer',
                 'introduction' => 'required',
-                'real_name' => 'required',
-                'mobile' => 'required|integer',
+                // 'real_name'=>'required',
+                // 'mobile'=>'required|integer',
                 'address_arr_id' => 'required',
                 'address' => 'required',
             ],
@@ -1018,9 +1002,9 @@ class NewsController extends AbstractController
                 'company_size.required' => '公司规模不能为空',
                 'company_size.integer' => '公司规模必须是整数',
                 'introduction.required' => '公司简介不能为空',
-                'real_name.required' => '联系人不能为空',
-                'mobile.required' => '联系电话不能为空',
-                'mobile.integer' => '联系电话必须是整数',
+                // 'real_name.required' => '联系人不能为空',
+                // 'mobile.required' => '联系电话不能为空',
+                // 'mobile.integer' => '联系电话必须是整数',
                 'address_arr_id.required' => '公司地址不能为空',
                 'address.required' => '公司详细地址不能为空',
             ]

+ 34 - 32
app/Middleware/Auth/FooMiddleware.php

@@ -39,22 +39,23 @@ class FooMiddleware implements MiddlewareInterface
 
     public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
     {
-
         $header = $request->getHeaders();
         try {
             if($header &&  isset($header['token']) && $header['token'][0]!='null' && $header['token'][0]!='' && isset($header['token'][0])){
-                var_dump("token类型:",$header['token'][0]);
                 $ver = $this->JWT->getClaimsByToken($header['token'][0]);
                 $tokenTime =  $this->JWT->getTokenDynamicCacheTime($header['token'][0]);
+                
                 if($tokenTime==0){
-                   return $this->response->json(
-                       [
-                           'code' => -1,
-                           'data' => [],
-                           'message' => 'token无效,请重新登录',
-                       ]
-                   );
+                    $response = $this->response->withStatus(401)
+                        ->withHeader('Content-Type', 'application/json')
+                        ->withBody(new \Hyperf\HttpMessage\Stream\SwooleStream(json_encode([
+                            'code' => -1,
+                            'data' => [],
+                            'message' => 'token无效,请重新登录'
+                        ])));
+                    return $response;
                 }
+
                 if($header['userurl'] && $header['userurl'][0]){
                     $origin = $header['userurl'][0];
                     $data = [
@@ -63,43 +64,44 @@ class FooMiddleware implements MiddlewareInterface
 
                     $result = $this->websiteServiceClient->getWebsiteId($data);
                     if(!isset($result['data']['id']) || !$result['data']['id']){
-                        return $this->response->json(
-                            [
+                        $response = $this->response->withStatus(404)
+                            ->withHeader('Content-Type', 'application/json')
+                            ->withBody(new \Hyperf\HttpMessage\Stream\SwooleStream(json_encode([
                                 'code' => -1,
                                 'data' => [],
-
-                                'message' => '网站不存在...',
-                            ]
-                        );
+                                'message' => '网站不存在...'
+                            ])));
+                        return $response;
                     }
                     Context::set("SiteId",$result['data']['id']);
                 }
-//                var_dump("中间件:",$ver);
+
                 Context::set("UserId",$ver['uid']);
                 Context::set("TypeId",$ver['type_id']);
+                
                 if ($ver) {
                     return $handler->handle($request);
                 }
-            }else{
-                return $this->response->json(
-                    [
-                        'code' => -1,
-                        'data' => [],
-                        'message' => 'token无效,请重新登录',
-                    ]
-                );
             }
 
-        }catch (\Exception $e){
-            var_dump("错误消息1:",$e->getMessage(),$e->getCode());
-            return $this->response->json(
-                [
+            $response = $this->response->withStatus(401)
+                ->withHeader('Content-Type', 'application/json')
+                ->withBody(new \Hyperf\HttpMessage\Stream\SwooleStream(json_encode([
+                    'code' => -1,
+                    'data' => [],
+                    'message' => 'token无效,请重新登录'
+                ])));
+            return $response;
+
+        } catch (\Exception $e) {
+            $response = $this->response->withStatus(500)
+                ->withHeader('Content-Type', 'application/json')
+                ->withBody(new \Hyperf\HttpMessage\Stream\SwooleStream(json_encode([
                     'code' => $e->getCode(),
                     'data' => [],
-                    'message' => $e->getMessage(),
-                ]
-            );
+                    'message' => $e->getMessage()
+                ])));
+            return $response;
         }
-        return false;
     }
 }

+ 0 - 95
app/Middleware/Auth/PublicMiddleware - 副本.php

@@ -1,95 +0,0 @@
-<?php
-
-declare(strict_types=1);
-
-namespace App\Middleware\Auth;
-
-use Hyperf\Di\Annotation\Inject;
-use Hyperf\HttpServer\Contract\RequestInterface;
-use Hyperf\HttpServer\Contract\ResponseInterface as HttpResponse;
-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 Hyperf\Context\Context;
-use App\JsonRpc\WebsiteServiceInterface;
-use Phper666\JWTAuth\JWT;
-class PublicMiddleware implements MiddlewareInterface
-{
-    protected ContainerInterface $container;
-
-    protected RequestInterface $request;
-
-    protected HttpResponse $response;
-    protected JWT $JWT;
-    /**
-     * @var WebsiteServiceInterface
-     */
-    #[Inject]
-    private $websiteServiceClient;
-    public function __construct(ContainerInterface $container, HttpResponse $response, RequestInterface $request,Jwt $JWT)
-    {
-        $this->container = $container;
-        $this->response = $response;
-        $this->request = $request;
-        $this->JWT = $JWT;
-
-    }
-
-    public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
-    {
-
-        $header = $request->getHeaders();
-        try {
-          
-            if($header &&  isset($header['userurl']) && $header['userurl'][0]!='null' && isset($header['userurl'][0])){
-                $origin = $header['userurl'][0];
-                $data = [
-                    'website_url'=>$origin
-                ];
-
-                $result = $this->websiteServiceClient->getWebsiteId($data);
-                if(!isset($result['data']['id']) || !$result['data']['id']){
-                    return $this->response->json(
-                        [
-                            'code' => -1,
-                            'data' => [],
-
-                            'message' => '网站不存在...',
-                        ]
-                    );
-                }
-//                var_dump($result['data']);
-                // var_dump("获取站点id:",$result);
-                Context::set("SiteId",$result['data']['id']);
-                if($result['data']['id']==1){
-                    Context::set("SiteId",0);
-                }
-
-                if ($result) {
-                    return $handler->handle($request);
-                }
-            }else{
-                return $this->response->json(
-                    [
-                        'code' => -1,
-                        'data' => [],
-                        'message' => 'userurl:必填',
-                    ]
-                );
-            }
-
-        }catch (\Exception $e){
-//            var_dump("错误消息:",$e->getMessage(),$e->getCode());
-            return $this->response->json(
-                [
-                    'code' => $e->getCode(),
-                    'data' => [],
-                    'message' => 'userurl必填:'.$e->getMessage(),
-                ]
-            );
-        }
-        return false;
-    }
-}

+ 38 - 35
app/Middleware/Auth/SensitiveMiddleware.php

@@ -15,6 +15,7 @@ use Psr\Http\Server\RequestHandlerInterface;
 use Hyperf\HttpMessage\Stream\SwooleStream;
 use Hyperf\Di\Annotation\Inject;
 use Hyperf\Redis\Redis;
+//use Swoole\Http\Request;
 class SensitiveMiddleware implements MiddlewareInterface
 {
     protected ContainerInterface $container;
@@ -24,6 +25,10 @@ class SensitiveMiddleware implements MiddlewareInterface
     protected HttpResponse $response;
     #[Inject]
     protected Redis $redis;
+    const STREAM_URL = [
+        '/news/addArticle',
+        '/news/updateArticle'
+    ];
     public function __construct( RequestInterface $request, HttpResponse $response)
     {
         $this->request = $request;
@@ -32,51 +37,49 @@ class SensitiveMiddleware implements MiddlewareInterface
 
     public function process(ServerRequestInterface $request, RequestHandlerInterface $handler): ResponseInterface
     {
+        $uri = $request->getUri();
+        $path = $uri->getPath();
+        
+        if (!$path || !in_array($path, self::STREAM_URL)) {
+            return $handler->handle($request);
+        }
+
         try {
-            $badWords = $this->redis->sMembers('black_word'); //黑名单
-            $whiteWords = $this->redis->sMembers('white_word');//白名单
-            // 获取所有请求参数并拼接成文本
+            $badWords = $this->redis->sMembers('black_word');
+            $whiteWords = $this->redis->sMembers('white_word');
             $params = $this->request->all();
             $concatenated = "";
-             if($params){
-                  foreach ($params as $value) {
-                      if (is_array($value)) {
-                          // 如果值是数组,将数组元素用逗号连接
-                          $concatenated.= json_encode($value);
-                      } else {
-                          // 如果不是数组,直接拼接
-                          $concatenated.= $value;
-                      }
-                  }
-              }
-            // 遍历违禁词,检查是否在文本中存在
+
+            if ($params) {
+                foreach ($params as $value) {
+                    if (is_array($value)) {
+                        $concatenated .= json_encode($value);
+                    } else {
+                        $concatenated .= (string)$value;
+                    }
+                }
+            }
+
             foreach ($badWords as $badWord) {
-                // 判断该违禁词是否在白名单中,如果在则跳过
                 if (in_array($badWord, $whiteWords)) {
                     continue;
                 }
                 if (str_contains($concatenated, $badWord)) {
-                    // 处理找到违禁词的情况,例如返回错误信息
-                    $message = '发现违禁词: '. $badWord;
-                    return $this->response->json(
-                        [
-                            'code' => 0,
-                            'data' => [],
-                            'message' => $message
-                        ]
-                    );
+                    return $this->response->raw(json_encode([
+                        'code' => 0,
+                        'data' => [],
+                        'message' => '发现违禁词: ' . $badWord
+                    ]));
                 }
             }
-          return $handler->handle($request);
-        }catch (\Exception $e){
-            return $this->response->json(
-                [
-                    'code' => $e->getCode(),
-                    'data' => [],
-                    'message' => '敏感词检测失败:'.$e->getMessage(),
-                ]
-            );
+
+            return $handler->handle($request);
+        } catch (\Exception $e) {
+            return $this->response->raw(json_encode([
+                'code' => -1,
+                'data' => [],
+                'message' => '系统错误:' . $e->getMessage()
+            ]));
         }
-        return false;
     }
 }

+ 3 - 1
config/api/login.php

@@ -20,8 +20,10 @@ Router::get('/api/loginStatus', 'App\Controller\LoginController@loginStatus');
 Router::get('/api/loginapi', 'App\Controller\LoginController@loginapi');
 //退出登陆
 Router::get('/api/logoutapi', 'App\Controller\LoginController@logoutapi');
-
+//跳转登陆
 Router::get('/api/goLogin', 'App\Controller\LoginController@goLogin');
+//退出登陆
 Router::get('/api/logout', 'App\Controller\LoginController@logout');
+//返回登陆
 Router::get('/api/backlogin', 'App\Controller\LoginController@backlogin');
 

+ 1 - 1
config/api/news.php

@@ -112,5 +112,5 @@ Router::addGroup(
 
         // 20250306 招聘
     },
-    ['middleware' => [FooMiddleware::class]]
+    ['middleware' => [FooMiddleware::class,\App\Middleware\Auth\SensitiveMiddleware::class]]
 );

+ 7 - 2
config/autoload/logger.php

@@ -12,10 +12,15 @@ declare(strict_types=1);
 return [
     'default' => [
         'handler' => [
-            'class' => Monolog\Handler\StreamHandler::class,
+            'class' => Monolog\Handler\RotatingFileHandler::class,
             'constructor' => [
-                'stream' => BASE_PATH . '/runtime/logs/hyperf.log',
+                'filename' => BASE_PATH . '/runtime/logs/hyperf.log',
+                'maxFiles' => 30, // 保留最近30天的日志文件
                 'level' => Monolog\Logger::DEBUG,
+                'bubble' => true,
+                'filePermission' => null,
+                'useLocking' => false,
+                'dateFormat' => 'Y-m-d', // 按天分割日志文件
             ],
         ],
         'formatter' => [