From b1d58ece61566431121fd7936335ef7aabfc0786 Mon Sep 17 00:00:00 2001 From: root Date: Thu, 26 Feb 2026 10:20:48 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20=E4=BD=BF=E7=94=A8=E9=A3=9E=E4=B9=A6?= =?UTF-8?q?=E5=AE=98=E6=96=B9=20passport=20=E6=8E=88=E6=9D=83=E7=AB=AF?= =?UTF-8?q?=E7=82=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 后端修改: - 授权 URL 从 open-apis 改为 passport.feishu.cn - 使用 passport 端点获取 user_access_token - 添加 httpGet 方法 前端修改: - 使用官方 tt.requestAuthCode() API(飞书内免登) - 保留轮询方式实现扫码登录 参考文档: https://open.feishu.cn/document/sso/web-application-sso/qr-sdk-documentation Co-Authored-By: Claude Opus 4.6 --- backend/app/controller/AuthController.php | 4 +- backend/app/service/FeishuService.php | 58 +++++++++++++++++++---- frontend/src/pages/login/QRCodeLogin.tsx | 4 ++ 3 files changed, 55 insertions(+), 11 deletions(-) diff --git a/backend/app/controller/AuthController.php b/backend/app/controller/AuthController.php index 86b94a6..0b52ca0 100644 --- a/backend/app/controller/AuthController.php +++ b/backend/app/controller/AuthController.php @@ -140,10 +140,10 @@ class AuthController extends BaseController 'expires_at' => date('Y-m-d H:i:s', time() + 300), // 5分钟过期 ]); - // 构建扫码登录 URL + // 构建扫码登录 URL(使用官方 passport 端点) $appId = 'cli_a8033d607cba500d'; $redirectUri = urlencode("https://xsm.dev.hnxinyouhe.com/login/qrcode/{$loginSession->id}"); - $authUrl = "https://open.feishu.cn/open-apis/authen/v1/oidc/authorize?app_id={$appId}&redirect_uri={$redirectUri}&state={$loginSession->id}"; + $authUrl = "https://passport.feishu.cn/suite/passport/oauth/authorize?client_id={$appId}&redirect_uri={$redirectUri}&response_type=code&state={$loginSession->id}"; // 生成二维码内容(返回 URL,前端生成二维码) return $this->success([ diff --git a/backend/app/service/FeishuService.php b/backend/app/service/FeishuService.php index 43927c4..b4cc0b8 100644 --- a/backend/app/service/FeishuService.php +++ b/backend/app/service/FeishuService.php @@ -134,28 +134,36 @@ class FeishuService } /** - * 根据 auth_code 获取用户信息 + * 根据 auth_code 获取用户信息(扫码登录) */ public function getUserInfo(string $authCode): array { $app = $this->getAppConfig(); - $token = $this->getAccessToken(); - // 获取用户 access_token - $response = $this->httpPost('https://open.feishu.cn/open-apis/authen/v1/oidc/access_token', [ + // 使用 passport 端点获取 user_access_token + $response = $this->httpPost('https://passport.feishu.cn/suite/passport/oauth/token', [ 'grant_type' => 'authorization_code', 'client_id' => $app['app_id'], 'client_secret' => $app['app_secret'], 'code' => $authCode, - ], [ - 'Authorization: Bearer ' . $token, ]); - if ($response['code'] !== 0) { - throw new \Exception('获取用户信息失败: ' . ($response['msg'] ?? '未知错误')); + if (!isset($response['access_token'])) { + throw new \Exception('获取 user_access_token 失败: ' . ($response['error_description'] ?? '未知错误')); } - return $response['data'] ?? []; + $userAccessToken = $response['access_token']; + + // 使用 user_access_token 获取用户信息 + $userInfo = $this->httpGet('https://passport.feishu.cn/suite/passport/oauth/userinfo', [ + 'access_token' => $userAccessToken, + ]); + + if (!isset($userInfo['data'])) { + throw new \Exception('获取用户信息失败'); + } + + return $userInfo['data']; } /** @@ -306,4 +314,36 @@ class FeishuService return $result; } + + /** + * HTTP GET 请求 + */ + private function httpGet(string $url, array $params = []): array + { + if (!empty($params)) { + $url .= '?' . http_build_query($params); + } + + $ch = curl_init(); + + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); + curl_setopt($ch, CURLOPT_TIMEOUT, 30); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); + + $response = curl_exec($ch); + $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); + + if ($httpCode !== 200) { + throw new \Exception("HTTP 请求失败: {$httpCode}"); + } + + $result = json_decode($response, true); + + if (json_last_error() !== JSON_ERROR_NONE) { + throw new \Exception('JSON 解析失败'); + } + + return $result; + } } diff --git a/frontend/src/pages/login/QRCodeLogin.tsx b/frontend/src/pages/login/QRCodeLogin.tsx index a6f555e..ae33146 100644 --- a/frontend/src/pages/login/QRCodeLogin.tsx +++ b/frontend/src/pages/login/QRCodeLogin.tsx @@ -175,6 +175,10 @@ export default function QRCodeLogin({ visible, onClose }: QRCodeLoginProps) { )} + +

+ 💡 打开飞书 APP,扫一扫登录 +

)}