Fallback SSO OAuth mint to browser PKCE when Python TLS fails.

HTTP mint often dies on auth.x.ai (curl OpenSSL / SSLEOFError); reuse the
registration browser to set SSO, complete authorize+consent, and fetch tokens
so CPA export/push to cpa.nopj.cn can continue.
This commit is contained in:
chaos committed 2026-07-14 10:04:55 +08:00
1 parent 2e833f2af3
commit 8b399277e7
4 files changed
+443 -9

No files matched your search

+39 -9
View File
@@ -72,13 +72,22 @@ def _mint_tokens(
log: Callable[[str], None],
proxy: str | None,
) -> dict[str, Any]:
"""优先 SSO 授权码;可选回退设备码。"""
from oidc_mint.oauth_code import OAuthCodeError, mint_from_sso, normalize_sso_cookie
"""优先 HTTP SSO 授权码;TLS 失败时用注册浏览器 PKCE;可选设备码。"""
from oidc_mint.oauth_code import (
OAuthCodeError,
_is_http_tls_failure,
mint_from_sso,
mint_from_sso_browser,
normalize_sso_cookie,
)
sso_token = normalize_sso_cookie(sso or "")
prefer_sso = bool(cfg.get("cpa_prefer_sso_oauth", True))
allow_browser = bool(cfg.get("cpa_allow_browser_fallback", True))
allow_device = bool(cfg.get("cpa_allow_device_fallback", False))
timeout = float(cfg.get("mint_timeout_sec", 300) or 300)
require_ref = bool(cfg.get("cpa_require_referrer", True))
http_err: Exception | None = None
if prefer_sso and sso_token:
log("[cpa] 使用 SSO→OAuth(PKCE, referrer=grok-build)")
@@ -87,21 +96,42 @@ def _mint_tokens(
sso_token,
proxy=proxy,
log=lambda m: log(f"[Debug] {m}"),
require_referrer=bool(cfg.get("cpa_require_referrer", True)),
require_referrer=require_ref,
)
except OAuthCodeError as exc:
http_err = exc
log(f"[!] SSO→OAuth 失败: {exc}")
if not allow_device:
raise
log("[cpa] 回退设备码铸造(可能缺 referrer)")
except Exception as exc: # noqa: BLE001
http_err = exc
log(f"[!] SSO→OAuth 异常: {exc}")
if not allow_device:
raise
log("[cpa] 回退设备码铸造(可能缺 referrer)")
# HTTP 失败后:有 page+sso 就优先浏览器 PKCE(Chrome TLS 通常正常,且保留 referrer)
if allow_browser and page is not None and sso_token and http_err is not None:
why = "TLS/连接" if _is_http_tls_failure(http_err) else "HTTP"
log(f"[cpa] 回退浏览器 PKCE 铸造({why}失败,绕开 Python TLS)")
try:
return mint_from_sso_browser(
sso_token,
page,
log=lambda m: log(f"[Debug] {m}"),
require_referrer=require_ref,
timeout_sec=min(timeout, 120.0),
)
except Exception as exc: # noqa: BLE001
log(f"[!] 浏览器 PKCE 失败: {exc}")
if not allow_device:
raise
log("[cpa] 继续回退设备码铸造(可能缺 referrer)")
elif http_err is not None and not allow_device:
raise http_err
if not allow_device and not sso_token:
raise RuntimeError("无 sso cookie,且已禁用设备码回退;无法铸造带 referrer 的 token")
if not allow_device:
# 有 sso 但 browser 也没开/没 page
if http_err is not None:
raise http_err
raise RuntimeError("SSO 铸造失败,且未启用任何回退")
# 设备码回退(旧路径,通常无 referrer)
from oidc_mint import mint_with_browser