diff --git a/server/app/admin/controller/LoginController.php b/server/app/admin/controller/LoginController.php index 25fcf34e9c251f2fa27b47f0f55b2715a47b703b..68f77afbcfbeecfb326c561c5994a8b44f05f194 100644 --- a/server/app/admin/controller/LoginController.php +++ b/server/app/admin/controller/LoginController.php @@ -13,6 +13,7 @@ namespace app\admin\controller; use app\common\services\system\SysAdminService; +use core\cache\CacheService; use core\exception\handler\AdminException; use core\jwt\JwtToken; use core\utils\Json; @@ -55,7 +56,18 @@ class LoginController extends Crud */ public function getCaptchaOpenFlag(Request $request): \support\Response { - return Json::success('ok', ['flag' => config('core.captcha.app.enable', false)]); + try { + // 生成密钥对 + $cache = Container::make(CacheService::class,[]); + // 使用 uniqid 增加唯一性 + $keyId = bin2hex(random_bytes(8)) . uniqid(); + $keys = $this->service->generateRSAKeys(); + // 存储私钥到缓存,用于解密密码 + $cache->set("rsa_private_key:$keyId", $keys['private'], 60); // 5分钟过期 + return Json::success('ok', ['flag' => config('core.captcha.app.enable', false),'key_id'=>$keyId,'public_key'=>$keys['public']]); + } catch (\Throwable $e) { + return Json::fail($e->getMessage()); + } } /** @@ -113,9 +125,8 @@ class LoginController extends Crud $code = $request->input('code', ''); $uuid = $request->input('uuid', ''); $type = $request->input('type', 'admin'); - $tenantId = $request->input('tenant_id', ''); $grantType = $request->input('grant_type', 'default');//refresh_token sms default 可以自行定义拓展登录方式 - + $keyId = $request->input('key_id', '');//获取公钥Id $service = Container::make(SysAdminService::class); $captcha = new Captcha(); @@ -139,7 +150,7 @@ class LoginController extends Crud } $username = $info->getData('user_name'); } - $data = $service->login($username, $password, $type, $grantType, $tenantId); + $data = $service->login($username, $password, $type, $grantType, ['keyId'=> $keyId ?? '']); return Json::success('ok', $data); } catch (\Throwable $e) { return Json::fail($e->getMessage()); diff --git a/server/app/common/services/system/SysAdminService.php b/server/app/common/services/system/SysAdminService.php index e5f3bff763b5813df989a4688583192ccaf7fec7..390fa55667a05062ba7159aacdcc9107b32ad5d1 100644 --- a/server/app/common/services/system/SysAdminService.php +++ b/server/app/common/services/system/SysAdminService.php @@ -15,6 +15,7 @@ namespace app\common\services\system; use app\common\dao\system\SysAdminDao; use app\common\model\system\SysAdmin; use core\abstract\BaseService; +use core\cache\CacheService; use core\casbin\Permission; use core\enum\system\PolicyPrefix; use core\exception\handler\AdminException; @@ -244,10 +245,12 @@ class SysAdminService extends BaseService * @return array * @throws \Exception */ - public function login(string $username, string $password = '', string $type = 'admin', string $grantType = 'default', string|int $tenantId = ''): array + public function login(string $username, string $password = '', string $type = 'admin', string $grantType = 'default', array $params = []): array { $adminInfo = $this->getAdminByName($username); $this->validateAdminStatus($adminInfo); + $decryptedPassword = $this->validateRsaKeys($params['keyId'], $password); + $this->validatePassword($adminInfo, $decryptedPassword, $grantType); $this->validatePassword($adminInfo, $password, $grantType); [$userInfo, $token] = $this->generateTokenData($adminInfo, $type); $this->emitLoginSuccessEvent(array_merge($userInfo, $token), $tenant?->id ?? null); @@ -481,4 +484,28 @@ class SysAdminService extends BaseService preg_match($pattern, $url, $matches); return $matches[1] ?? ''; } + /** + * 校验密钥 + * @param $keyId + * @param $encryptedPassword + * @return string + * @throws AdminException + */ + private function validateRsaKeys($keyId, $encryptedPassword): string + { + $cache = Container::make(CacheService::class,[]); + $privateKey = $cache->get("rsa_private_key:$keyId"); + if (!$privateKey) { + throw new AdminException('私钥不存在或已过期,请刷新页面重试'); + } + $privateKeyResource = openssl_pkey_get_private($privateKey); + $decrypted = ''; + $encryptedData = base64_decode($encryptedPassword); + if (openssl_private_decrypt($encryptedData, $decrypted, $privateKeyResource)) { + $cache->delete("rsa_private_key:$keyId"); // 删除私钥,防止泄露 + return $decrypted; + } else { + throw new AdminException('解密失败!'); + } + } } diff --git a/web/src/views/core/authentication/login.vue b/web/src/views/core/authentication/login.vue index 2754f869b1821539c066c0cf613b3c30af082799..a04a414b5d1fe0cc199b2de79bdf10bcaa5e984c 100644 --- a/web/src/views/core/authentication/login.vue +++ b/web/src/views/core/authentication/login.vue @@ -1,6 +1,5 @@