From 4ddf4921b2bce7467b014a5803473672b7a5f830 Mon Sep 17 00:00:00 2001 From: mzl Date: Mon, 7 Jul 2025 18:34:21 +0800 Subject: [PATCH] =?UTF-8?q?=E7=99=BB=E5=BD=95=E4=B8=AD=E5=BF=83=E5=8A=9F?= =?UTF-8?q?=E8=83=BD=E5=BC=80=E5=8F=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/common/controller/AuthController.php | 10 ++ app/common/controller/BaseController.php | 2 - app/common/logic/AuthLogic.php | 52 ++++++++++ app/common/model/Corp.php | 49 ++++++++++ app/common/model/CorpFeishuApp.php | 56 +++++++++++ app/common/service/AuthService.php | 9 ++ app/common/service/BasicDataService.php | 118 +++++++++++++++++++++++ app/common/traits/ResponseTrait.php | 4 +- app/common/validate/UserValidate.php | 17 +++- app/middleware/AccessControl.php | 25 +++++ app/middleware/BasicDataMiddleware.php | 30 ++++++ config/middleware.php | 6 +- config/route.php | 1 + 13 files changed, 372 insertions(+), 7 deletions(-) create mode 100644 app/common/model/Corp.php create mode 100644 app/common/model/CorpFeishuApp.php create mode 100644 app/common/service/BasicDataService.php create mode 100644 app/middleware/AccessControl.php create mode 100644 app/middleware/BasicDataMiddleware.php diff --git a/app/common/controller/AuthController.php b/app/common/controller/AuthController.php index df35e72..c03c7f6 100644 --- a/app/common/controller/AuthController.php +++ b/app/common/controller/AuthController.php @@ -8,6 +8,16 @@ use support\Request; class AuthController extends BaseController { + + public function feishuScope(Request $request) + { + try { + $result = (new AuthService())->feishuAuthorize($request->corp_abbr, $request->system_code); + return $this->success($result); + } catch (\Throwable $e) { + return $this->error($e->getMessage()); + } + } public function login(Request $request) { diff --git a/app/common/controller/BaseController.php b/app/common/controller/BaseController.php index 10b3e95..f399906 100644 --- a/app/common/controller/BaseController.php +++ b/app/common/controller/BaseController.php @@ -2,8 +2,6 @@ namespace app\common\controller; -use support\Request; -use support\Response; use support\exception\BusinessException; use app\common\traits\ResponseTrait; use think\Validate; diff --git a/app/common/logic/AuthLogic.php b/app/common/logic/AuthLogic.php index de97262..0270f17 100644 --- a/app/common/logic/AuthLogic.php +++ b/app/common/logic/AuthLogic.php @@ -2,6 +2,8 @@ namespace app\common\logic; +use app\common\model\Corp; +use app\common\model\CorpFeishuApp; use app\common\model\UserTokenLog; use app\common\model\Systems; use app\common\model\User; @@ -375,6 +377,30 @@ class AuthLogic return $system; } + /** + * 公司验证 + */ + private function validateCorp(string $corpAbbr) + { + $corp = Corp::where('abbr', $corpAbbr)->first(); + if (!$corp) { + throw new BusinessException('公司不存在', 403); + } + return $corp; + } + + /** + * 飞书应用信息 + */ + private function validateFeishuApp(int $corpId, string $systemCode) + { + $feishuAppInfo = CorpFeishuApp::where('corp_id', $corpId)->where('system_code', $systemCode)->first(); + if (!$feishuAppInfo) { + throw new BusinessException('飞书应用不存在', 403); + } + return $feishuAppInfo; + } + /** * 用户系统权限校验 */ @@ -450,6 +476,16 @@ class AuthLogic */ private function getFeishuUserInfo(string $code) { + // // 获取凭证 + // $certificate = certificate($param['state']); + // // 获取token + // $class = new Feishu($certificate['appId'], $certificate['appSecre_s'], $param['state']); + // $userAccessToken = $class->userAccessToken($param['code'], $certificate['rUrl']); + // // 获取用户信息 + // $rst = $class->userInfo($userAccessToken['access_token']); + // if ($rst['code'] != 0) { + // throw new BusinessException('授权失败,请重试'); + // } // 实际实现需要调用飞书 API return [ 'user_id' => 'feishu_user_123', @@ -472,4 +508,20 @@ class AuthLogic } return $user; } + + /** + * 飞书应用信息 + */ + public function feishuAppInfo(string $corpAbbr, string $systemCode) + { + $corpInfo = $this->validateCorp($corpAbbr); + $fsAppInfo = $this->validateFeishuApp($corpInfo->id, $systemCode); + return [ + 'app_id' => $fsAppInfo->app_id, + 'app_secret' => $fsAppInfo->app_secret, + 'r_url' => $fsAppInfo->r_url, + 'scope' => $fsAppInfo->scopes, + 'state' => $fsAppInfo->state + ]; + } } \ No newline at end of file diff --git a/app/common/model/Corp.php b/app/common/model/Corp.php new file mode 100644 index 0000000..52c160e --- /dev/null +++ b/app/common/model/Corp.php @@ -0,0 +1,49 @@ +feishuAppInfo($corpAbbr, $systemCcode); + } + /** * 登录,支持多类型 */ diff --git a/app/common/service/BasicDataService.php b/app/common/service/BasicDataService.php new file mode 100644 index 0000000..af63d7a --- /dev/null +++ b/app/common/service/BasicDataService.php @@ -0,0 +1,118 @@ +checkParamInCache($loginTypeKey, $loginType)) { + // 如果 Redis 没有缓存,执行数据库查询并存入缓存 + $this->cacheLoginType($loginTypeKey, $loginType); + } + + // 检查缓存中是否有系统码参数 + if (!$this->checkParamInCache($systemCodeKey, $systemCode)) { + // 如果 Redis 没有缓存,执行数据库查询并存入缓存 + $this->cacheSystemCode($systemCodeKey, $systemCode); + } + + // 检查缓存中是否有公司标识参数 + if (!$this->checkParamInCache($corpAbbrKey, $corpAbbr)) { + // 如果 Redis 没有缓存,执行数据库查询并存入缓存 + $this->cacheCorpAbbr($corpAbbrKey, $corpAbbr); + } + + return true; + } + + /** + * 检查参数是否在 Redis 缓存中 + */ + private function checkParamInCache($cacheKey, $param) + { + return Redis::get($cacheKey) === $param; + } + + /** + * 缓存登录类型 + */ + private function cacheLoginType($cacheKey, $loginType) + { + // 假设我们从数据库或其他来源验证 loginType 的合法性 + if (!$this->validateLoginType($loginType)) { + throw new BusinessException('无效的登录方式'); + } + // 存入缓存,缓存有效期可以根据需求调整 + Redis::setex($cacheKey, 3600, $loginType); // 1小时有效期 + } + + /** + * 缓存系统码 + */ + private function cacheSystemCode($cacheKey, $systemCode) + { + // 假设我们从数据库或其他来源验证 systemCode 的合法性 + if (!$this->validateSystemCode($systemCode)) { + throw new BusinessException('无效的系统码'); + } + // 存入缓存,缓存有效期可以根据需求调整 + Redis::setex($cacheKey, 3600, $systemCode); // 1小时有效期 + } + + /** + * 缓存公司标识 + */ + private function cacheCorpAbbr($cacheKey, $corpAbbr) + { + // 假设我们从数据库或其他来源验证 corpAbbr 的合法性 + if (!$this->validateCorpAbbr($corpAbbr)) { + throw new BusinessException('无效的公司标识'); + } + // 存入缓存,缓存有效期可以根据需求调整 + Redis::setex($cacheKey, 3600, $corpAbbr); // 1小时有效期 + } + + /** + * 验证登录方式 + */ + private function validateLoginType($loginType) + { + // 假设这里是验证登录方式的具体逻辑 + return in_array($loginType, ['upwd', 'feishu', 'qrcode']); + } + + /** + * 验证系统码 + */ + private function validateSystemCode($systemCode) + { + // 假设这里是验证系统码的具体逻辑 + $system = Systems::where('code', $systemCode)->first(); + return $system !== null; + } + + /** + * 验证公司标识 + */ + private function validateCorpAbbr($corpAbbr) + { + // 假设这里是验证公司标识的具体逻辑 + $company = Corp::where('abbr', $corpAbbr)->first(); + return $company !== null; + } +} diff --git a/app/common/traits/ResponseTrait.php b/app/common/traits/ResponseTrait.php index 227fa99..f15dc92 100644 --- a/app/common/traits/ResponseTrait.php +++ b/app/common/traits/ResponseTrait.php @@ -19,7 +19,7 @@ trait ResponseTrait public function success( $data = [], string $message = '请求成功', - int $code = 0, + int $code = 200, int $httpStatus = 200, array $header = ['Content-Type' => 'application/json'] ): Response { @@ -38,7 +38,7 @@ trait ResponseTrait */ public function error( string $message = '请求失败', - int $code = 1, + int $code = 400, int $httpStatus = 400, $data = [], array $header = ['Content-Type' => 'application/json'] diff --git a/app/common/validate/UserValidate.php b/app/common/validate/UserValidate.php index 415ee0b..f161ba3 100644 --- a/app/common/validate/UserValidate.php +++ b/app/common/validate/UserValidate.php @@ -2,6 +2,7 @@ namespace app\common\validate; +use app\common\model\Corp; use app\common\model\Systems; use app\common\model\User; use think\Validate; @@ -17,7 +18,8 @@ class UserValidate extends Validate 'phone' => 'checkMobile|checkPhoneUnique', 'email' => 'email|checkEmailUnique', 'login_type' => 'require|in:upwd,feishu,qrcode', - 'system_code' => 'require|checkSystemCode' + 'system_code' => 'require|checkSystemCode', + 'corp_abbr' => 'require|checkCorpAbbr', ]; protected $message = [ @@ -40,12 +42,15 @@ class UserValidate extends Validate 'login_type.require' => '请选择登录方式', 'login_type.in' => '登录方式不支持', 'system_code.require' => '系统码不能为空', - 'system_code.checkSystemCode' => '系统码不存在或不合法' + 'system_code.checkSystemCode' => '系统码不存在或不合法', + 'corp_abbr.require' => '公司标识不能为空', + 'corp_abbr.checkCorpAbbr' => '公司标识不存在或不合法' ]; protected $scene = [ 'upwd_register' => ['name', 'account', 'password', 'confirm_password', 'login_type', 'system_code'], 'upwd_login' => ['account', 'password', 'login_type', 'system_code'], + 'feishu_auth' => ['corp_abbr', 'system_code', 'login_type'] ]; /** @@ -129,4 +134,12 @@ class UserValidate extends Validate { return Systems::where('code', $value)->exists(); } + + /** + * 验证 corp_abbr 企业标识是否存在 + */ + protected function checkCorpAbbr($value, $rule, $data, $field) + { + return Corp::where('abbr', $value)->exists(); + } } \ No newline at end of file diff --git a/app/middleware/AccessControl.php b/app/middleware/AccessControl.php new file mode 100644 index 0000000..6fa3822 --- /dev/null +++ b/app/middleware/AccessControl.php @@ -0,0 +1,25 @@ +method() == 'OPTIONS' ? response('') : $handler($request); + + // 给响应添加跨域相关的http头 + $response->withHeaders([ + 'Access-Control-Allow-Credentials' => 'true', + 'Access-Control-Allow-Origin' => $request->header('origin', '*'), + 'Access-Control-Allow-Methods' => $request->header('access-control-request-method', '*'), + 'Access-Control-Allow-Headers' => $request->header('access-control-request-headers', '*'), + ]); + + return $response; + } +} \ No newline at end of file diff --git a/app/middleware/BasicDataMiddleware.php b/app/middleware/BasicDataMiddleware.php new file mode 100644 index 0000000..6929ef8 --- /dev/null +++ b/app/middleware/BasicDataMiddleware.php @@ -0,0 +1,30 @@ +header('login_type'); + $systemCode = $request->header('system_code'); + $corpAbbr = $request->header('corp_abbr'); + $basicDataService = new BasicDataService(); + if ($basicDataService->checkAndCacheBaseParams($loginType, $systemCode, $corpAbbr)) { + $request->login_type = $loginType; + $request->system_code = $systemCode; + $request->corp_abbr = $corpAbbr; + } + return $next($request); + } catch (\Throwable $th) { + throw $th; + } + } + +} diff --git a/config/middleware.php b/config/middleware.php index 8e964ed..5512630 100644 --- a/config/middleware.php +++ b/config/middleware.php @@ -12,4 +12,8 @@ * @license http://www.opensource.org/licenses/mit-license.php MIT License */ -return []; \ No newline at end of file +return [ + '' => [ + \app\middleware\BasicDataMiddleware::class + ] +]; \ No newline at end of file diff --git a/config/route.php b/config/route.php index 8870d47..aaf9098 100644 --- a/config/route.php +++ b/config/route.php @@ -30,5 +30,6 @@ Route::group('/common', function () { Route::group('/auth', function () { Route::post('/login', [app\common\controller\AuthController::class, 'login']); Route::post('/register', [app\common\controller\AuthController::class, 'register']); + Route::post('/feishu/scope', [app\common\controller\AuthController::class, 'feishuScope']); }); }); \ No newline at end of file