Skip to content

Commit bbc0a1f

Browse files
fix(plugin): 兼容旧版 Session Token 与新版 Cookie 同步
- 插件接口同时接收 session_token 和 google_cookies - 优先校验 Session Token,失效时回退 Cookie 协议登录 - 根据可用登录态保存对应的刷新模式 - 使用解析出的账号邮箱更新 Token
1 parent 0d90066 commit bbc0a1f

1 file changed

Lines changed: 58 additions & 28 deletions

File tree

‎src/api/admin.py‎

Lines changed: 58 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2343,49 +2343,63 @@ async def update_plugin_config(
23432343

23442344
@router.post("/api/plugin/update-token")
23452345
async def plugin_update_token(request: dict, authorization: Optional[str] = Header(None)):
2346-
"""Receive modern Google Flow cookies from the Chrome extension."""
2346+
"""Receive a legacy session token and/or modern Google Flow cookies."""
23472347
await _verify_plugin_connection_token(authorization)
23482348
plugin_config = await db.get_plugin_config()
23492349

2350+
session_token_raw = request.get("session_token")
2351+
if session_token_raw is not None and not isinstance(session_token_raw, str):
2352+
raise HTTPException(status_code=400, detail="session_token must be a string")
2353+
session_token = (session_token_raw or "").strip()
2354+
if len(session_token) > 262144:
2355+
raise HTTPException(status_code=413, detail="session_token is too large")
2356+
23502357
google_cookies_raw = request.get("google_cookies")
23512358
if google_cookies_raw is not None and not isinstance(google_cookies_raw, str):
23522359
raise HTTPException(status_code=400, detail="google_cookies must be a string")
23532360

23542361
google_cookies = (google_cookies_raw or "").strip()
23552362
if len(google_cookies) > 524288:
23562363
raise HTTPException(status_code=413, detail="google_cookies is too large")
2357-
if not google_cookies:
2358-
raise HTTPException(status_code=400, detail="Missing google_cookies")
2364+
if not session_token and not google_cookies:
2365+
raise HTTPException(status_code=400, detail="Missing session_token or google_cookies")
23592366

23602367
proxy_url = str(request.get("proxy_url") or "").strip() or None
23612368
login_account_hint = str(request.get("login_account") or "").strip() or None
2362-
try:
2363-
protocol_result = await protocol_loginer.login(
2364-
google_cookies,
2365-
proxy=proxy_url,
2366-
email=login_account_hint,
2367-
)
2368-
except Exception as exc:
2369-
raise HTTPException(
2370-
status_code=400,
2371-
detail=f"Failed to derive session token from Google cookies: {str(exc)}",
2372-
) from exc
23732369

2374-
session_token = str(protocol_result.get("session_token") or "").strip()
2375-
if not protocol_result.get("success") or not session_token:
2376-
error = str(protocol_result.get("error") or "Google session is invalid or expired")
2377-
raise HTTPException(status_code=400, detail=f"Invalid Google cookies: {error}")
2370+
async def derive_session_token_from_cookies() -> str:
2371+
try:
2372+
protocol_result = await protocol_loginer.login(
2373+
google_cookies,
2374+
proxy=proxy_url,
2375+
email=login_account_hint,
2376+
)
2377+
except Exception as exc:
2378+
raise HTTPException(
2379+
status_code=400,
2380+
detail=f"Failed to derive session token from Google cookies: {str(exc)}",
2381+
) from exc
2382+
2383+
derived_token = str(protocol_result.get("session_token") or "").strip()
2384+
if not protocol_result.get("success") or not derived_token:
2385+
error = str(protocol_result.get("error") or "Google session is invalid or expired")
2386+
raise HTTPException(status_code=400, detail=f"Invalid Google cookies: {error}")
2387+
return derived_token
2388+
2389+
supplied_session_token = bool(session_token)
2390+
if not session_token:
2391+
session_token = await derive_session_token_from_cookies()
23782392

23792393
# Step 1: Convert ST to AT to get user info (including email)
2380-
try:
2381-
result = await token_manager.flow_client.st_to_at(session_token)
2394+
async def validate_session_token(value: str):
2395+
result = await token_manager.flow_client.st_to_at(value)
23822396
at = result["access_token"]
23832397
expires = result.get("expires")
23842398
user_info = result.get("user", {})
23852399
email = user_info.get("email", "")
23862400

23872401
if not email:
2388-
raise HTTPException(status_code=400, detail="Failed to get email from session token")
2402+
raise ValueError("Failed to get email from session token")
23892403

23902404
# Parse expiration time
23912405
from datetime import datetime
@@ -2395,14 +2409,30 @@ async def plugin_update_token(request: dict, authorization: Optional[str] = Head
23952409
at_expires = datetime.fromisoformat(expires.replace('Z', '+00:00'))
23962410
except (TypeError, ValueError):
23972411
pass
2412+
return at, at_expires, email
23982413

2399-
except HTTPException:
2400-
raise
2401-
except Exception as e:
2402-
raise HTTPException(status_code=400, detail=f"Invalid session token: {str(e)}")
2403-
2404-
protocol_mode = "protocol"
2405-
login_account = login_account_hint or email
2414+
try:
2415+
at, at_expires, email = await validate_session_token(session_token)
2416+
except Exception as direct_error:
2417+
if not supplied_session_token or not google_cookies:
2418+
raise HTTPException(
2419+
status_code=400,
2420+
detail=f"Invalid session token: {str(direct_error)}",
2421+
) from direct_error
2422+
2423+
# Browser profiles can retain an expired legacy ST while their Google
2424+
# cookies are still valid. Fall back to protocol login before failing.
2425+
session_token = await derive_session_token_from_cookies()
2426+
try:
2427+
at, at_expires, email = await validate_session_token(session_token)
2428+
except Exception as fallback_error:
2429+
raise HTTPException(
2430+
status_code=400,
2431+
detail=f"Invalid session token: {str(fallback_error)}",
2432+
) from fallback_error
2433+
2434+
protocol_mode = "protocol" if google_cookies else "session"
2435+
login_account = email
24062436

24072437
# Step 2: Check if token with this email exists
24082438
existing_token = await db.get_token_by_email(email)

0 commit comments

Comments
 (0)