重构为 HTTP SSO 扫码方案并引入 Vue3 前端

移除 Playwright 浏览器自动化,改用 passport/SSO HTTP 接口获取二维码与轮询登录;后端模块化拆分,前端替换为 Vue3 SPA。

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
travel
2026-06-25 10:47:55 +08:00
parent 853dacf528
commit 9e0644095f
33 changed files with 4792 additions and 1640 deletions
+64
View File
@@ -0,0 +1,64 @@
import json
import logging
import time
import requests
logger = logging.getLogger(__name__)
def get_proxy_from_api(api_url, max_retries=3, timeout=10):
if not api_url:
return None
last_error = None
for attempt in range(max_retries):
try:
resp = requests.get(api_url, timeout=timeout)
resp.raise_for_status()
content = resp.text.strip()
if not content:
raise ValueError("代理 API 返回空内容")
try:
data = resp.json()
if "ip" in data and "port" in data:
proxy_str = f"{data['ip']}:{data['port']}"
else:
proxy_str = content
except json.JSONDecodeError:
proxy_str = content
if not proxy_str.startswith(("http://", "https://")):
proxy_str = f"http://{proxy_str}"
return {"server": proxy_str}
except Exception as e:
last_error = e
if attempt < max_retries - 1:
wait = 2 ** attempt
logger.warning("获取代理失败 (第%s次): %s%ss 后重试", attempt + 1, e, wait)
time.sleep(wait)
logger.error("获取代理失败,已重试%s次: %s", max_retries, last_error)
return None
def test_proxy_api(proxy_api):
proxy = get_proxy_from_api(proxy_api, timeout=5)
if not proxy:
return {"status": "error", "message": "获取代理失败"}
proxies = {"http": proxy["server"], "https": proxy["server"]}
test_urls = [
"http://httpbin.org/ip",
"https://api.ipify.org?format=json",
]
last_err = None
for test_url in test_urls:
try:
resp = requests.get(test_url, proxies=proxies, timeout=10)
if resp.status_code == 200:
try:
data = resp.json()
ip = data.get("origin") or data.get("ip", "unknown")
except json.JSONDecodeError:
ip = resp.text.strip()[:64] or "unknown"
return {"status": "success", "ip": ip, "message": "代理可用"}
except Exception as e:
last_err = e
return {"status": "error", "message": f"代理测试失败: {last_err}"}