handle_proxy_callback($provider); } else { $this->handle_proxy_request($provider); } } private function handle_proxy_request(string $provider): void { $secret = AKSRT_Settings::oauth_proxy_secret(); if (empty($secret)) { wp_die(__('代理登录服务端未配置密钥', 'aksrt')); } $agent_back_url = esc_url_raw($_GET['agent_back_url'] ?? ''); $sign = sanitize_text_field($_GET['sign'] ?? ''); $action = sanitize_key($_GET['action'] ?? 'login'); if (empty($agent_back_url) || empty($sign)) { wp_die(__('代理请求参数不完整', 'aksrt')); } $verify_params = $_GET; unset($verify_params['sign']); if (!$this->verify_sign($verify_params, $secret, $sign)) { wp_die(__('代理请求签名验证失败', 'aksrt')); } $ts = (int) ($_GET['ts'] ?? 0); if (abs(time() - $ts) > 300) { wp_die(__('代理请求已过期,请重试', 'aksrt')); } @session_start(); $_SESSION['aksrt_proxy_agent_back_url'] = $agent_back_url; $_SESSION['aksrt_proxy_action'] = $action; $_SESSION['aksrt_proxy_nonce'] = sanitize_text_field($_GET['nonce'] ?? ''); $_SESSION['aksrt_proxy_uid'] = (int) ($_GET['uid'] ?? 0); try { $oauth = AKSRT_OAuth::get_instance(); $auth_url = $oauth->get_auth_url($provider, $action); if (empty($auth_url)) { wp_die(__('无法生成授权链接', 'aksrt')); } wp_safe_redirect($auth_url); exit; } catch (\Exception $e) { wp_die(__('代理登录错误:', 'aksrt') . esc_html($e->getMessage())); } } private function handle_proxy_callback(string $provider): void { @session_start(); $agent_back_url = $_SESSION['aksrt_proxy_agent_back_url'] ?? ''; if (empty($agent_back_url)) return; $_SESSION['aksrt_proxy_agent_back_url'] = ''; $_SESSION['aksrt_proxy_action'] = ''; $_SESSION['aksrt_proxy_nonce'] = ''; $_SESSION['aksrt_proxy_uid'] = 0; $secret = AKSRT_Settings::oauth_proxy_secret(); if (empty($secret)) { wp_die(__('代理登录服务端配置错误', 'aksrt')); } $error = $_GET['error'] ?? ''; if ($error) { wp_safe_redirect(add_query_arg(['error' => urlencode($error)], $agent_back_url)); exit; } $code = sanitize_text_field($_GET['code'] ?? ''); if (empty($code)) { wp_safe_redirect(add_query_arg(['error' => urlencode('missing_code')], $agent_back_url)); exit; } try { $user_data = $this->fetch_user_data($provider, $code); if (empty($user_data['provider_id'])) { wp_safe_redirect(add_query_arg(['error' => urlencode('no_user_info')], $agent_back_url)); exit; } $callback_params = [ 'provider' => $provider, 'provider_id' => $user_data['provider_id'], 'username' => $user_data['username'] ?? '', 'name' => $user_data['name'] ?? '', 'email' => $user_data['email'] ?? '', 'email_verified' => !empty($user_data['email_verified']) ? '1' : '0', 'avatar_url' => $user_data['avatar_url'] ?? '', 'bio' => $user_data['bio'] ?? '', 'action' => sanitize_key($_SESSION['aksrt_proxy_action'] ?? 'login'), 'ts' => time(), ]; $callback_params['sign'] = $this->sign($callback_params, $secret); $redirect_url = $agent_back_url . (strpos($agent_back_url, '?') !== false ? '&' : '?') . http_build_query($callback_params); wp_safe_redirect($redirect_url); exit; } catch (\Exception $e) { wp_safe_redirect(add_query_arg(['error' => urlencode($e->getMessage())], $agent_back_url)); exit; } } /** * 获取用户数据 */ private function fetch_user_data(string $provider, string $code): array { $config = get_option('aksrt_oauth', [])[$provider] ?? []; if (empty($config['client_id']) || empty($config['client_secret'])) { throw new \Exception(__('未配置此平台的 OAuth 凭据', 'aksrt')); } $redirect_uri = !empty($config['redirect_uri']) ? $config['redirect_uri'] : home_url('/oauth/proxy/' . $provider . '/callback'); switch ($provider) { case 'github': $oauth = new \Yurun\OAuthLogin\Github\OAuth2( $config['client_id'], $config['client_secret'], $redirect_uri ); $oauth->getAccessToken($_GET['state'] ?? '', $code, $_GET['state'] ?? null); $userInfo = $oauth->getUserInfo(); $email = $userInfo['email'] ?? ''; if (empty($email)) { $emails_json = $oauth->http->header('Authorization', ' token ' . $oauth->accessToken) ->get('https://api.github.com/user/emails') ->body(); $emails = json_decode($emails_json, true) ?: []; foreach ($emails as $em) { if (!empty($em['primary']) && !empty($em['email'])) { $email = $em['email']; break; } } } return [ 'provider' => 'github', 'provider_id' => (string) ($userInfo['id'] ?? ''), 'username' => $userInfo['login'] ?? '', 'name' => $userInfo['name'] ?? '', 'email' => $email, 'avatar_url' => $userInfo['avatar_url'] ?? '', 'bio' => $userInfo['bio'] ?? '', ]; case 'gitee': $oauth = new \Yurun\OAuthLogin\Gitee\OAuth2( $config['client_id'], $config['client_secret'], $redirect_uri ); $oauth->getAccessToken($_GET['state'] ?? '', $code, $_GET['state'] ?? null); $userInfo = $oauth->getUserInfo(); return [ 'provider' => 'gitee', 'provider_id' => (string) ($userInfo['id'] ?? ''), 'username' => $userInfo['login'] ?? '', 'name' => $userInfo['name'] ?? '', 'email' => $userInfo['email'] ?? '', 'avatar_url' => $userInfo['avatar_url'] ?? '', 'bio' => $userInfo['bio'] ?? '', ]; case 'qq': $oauth = new \Yurun\OAuthLogin\QQ\OAuth2( $config['client_id'], $config['client_secret'], $redirect_uri ); $oauth->getAccessToken($_GET['state'] ?? '', $code, $_GET['state'] ?? null); $openid = $oauth->getOpenID(); $userInfo = $oauth->getUserInfo(); return [ 'provider' => 'qq', 'provider_id' => $openid, 'username' => $userInfo['nickname'] ?? '', 'name' => $userInfo['nickname'] ?? '', 'email' => '', 'avatar_url' => $userInfo['figureurl_qq_2'] ?? $userInfo['figureurl_2'] ?? '', ]; case 'google': $response = wp_remote_post('https://oauth2.googleapis.com/token', [ 'body' => [ 'code' => $code, 'client_id' => $config['client_id'], 'client_secret' => $config['client_secret'], 'redirect_uri' => $redirect_uri, 'grant_type' => 'authorization_code', ], ]); if (is_wp_error($response)) throw new \Exception($response->get_error_message()); $token_data = json_decode(wp_remote_retrieve_body($response), true); if (empty($token_data['access_token'])) throw new \Exception(__('Google token 获取失败', 'aksrt')); $user_response = wp_remote_get('https://www.googleapis.com/oauth2/v2/userinfo', [ 'headers' => ['Authorization' => 'Bearer ' . $token_data['access_token']], ]); if (is_wp_error($user_response)) throw new \Exception($user_response->get_error_message()); $user_info = json_decode(wp_remote_retrieve_body($user_response), true); return [ 'provider' => 'google', 'provider_id' => (string) ($user_info['id'] ?? ''), 'username' => $user_info['email'] ?? '', 'name' => $user_info['name'] ?? '', 'email' => $user_info['email'] ?? '', 'avatar_url' => $user_info['picture'] ?? '', ]; default: throw new \Exception(__('不支持的 OAuth 平台', 'aksrt')); } } private function sign(array $data, string $secret): string { unset($data['sign']); ksort($data); return hash_hmac('sha256', http_build_query($data), $secret); } private function verify_sign(array $data, string $secret, string $expected_sign): bool { return hash_equals($this->sign($data, $secret), $expected_sign); } } return AKSRT_OAuth_Proxy_Server::get_instance();