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,扫一扫登录 +
> )}