diff --git a/backend/api_service/app/routers/accounts.py b/backend/api_service/app/routers/accounts.py index 51baece..bcacb18 100644 --- a/backend/api_service/app/routers/accounts.py +++ b/backend/api_service/app/routers/accounts.py @@ -210,14 +210,18 @@ async def _verify_weibo_cookie(cookie_str: str) -> dict: Returns {"valid": bool, "uid": str|None, "screen_name": str|None}. """ cookies = _parse_cookie_str(cookie_str) - async with httpx.AsyncClient(timeout=15, follow_redirects=True) as client: - # Step 1: check login via /ajax/side/cards + async with httpx.AsyncClient(timeout=15, follow_redirects=False) as client: + # Step 1: check login via /ajax/side/cards (不跟随重定向) resp = await client.get( "https://weibo.com/ajax/side/cards", params={"count": "1"}, - headers=WEIBO_HEADERS, + headers={**WEIBO_HEADERS, "X-Requested-With": "XMLHttpRequest"}, cookies=cookies, ) + + if resp.status_code in (301, 302): + return {"valid": False, "uid": None, "screen_name": None} + try: data = resp.json() except Exception: @@ -346,10 +350,9 @@ async def _get_super_topics(cookie_str: str, weibo_uid: str = "") -> List[dict]: cookies = _parse_cookie_str(cookie_str) topics: List[dict] = [] - async with httpx.AsyncClient(timeout=15, follow_redirects=True) as client: - # First get XSRF-TOKEN by visiting weibo.com - await client.get("https://weibo.com/", headers=WEIBO_HEADERS, cookies=cookies) - xsrf = client.cookies.get("XSRF-TOKEN", "") + async with httpx.AsyncClient(timeout=15, follow_redirects=False) as client: + # 直接请求 API,不访问首页(避免 SSO 重定向) + xsrf = cookies.get("XSRF-TOKEN", "") headers = { **WEIBO_HEADERS, @@ -414,10 +417,9 @@ async def _do_signin(cookie_str: str, topic_title: str, containerid: str) -> dic import time as _time cookies = _parse_cookie_str(cookie_str) - async with httpx.AsyncClient(timeout=15, follow_redirects=True) as client: - # Get XSRF-TOKEN - await client.get("https://weibo.com/", headers=WEIBO_HEADERS, cookies=cookies) - xsrf = client.cookies.get("XSRF-TOKEN", "") + async with httpx.AsyncClient(timeout=15, follow_redirects=False) as client: + # 直接从 Cookie 获取 XSRF,不访问首页 + xsrf = cookies.get("XSRF-TOKEN", "") headers = { **WEIBO_HEADERS, @@ -448,6 +450,10 @@ async def _do_signin(cookie_str: str, topic_title: str, containerid: str) -> dic headers=headers, cookies=cookies, ) + + if resp.status_code in (301, 302): + return {"status": "failed", "message": "签到API被重定向,Cookie可能失效"} + try: data = resp.json() except Exception: diff --git a/backend/task_scheduler/app/main.py b/backend/task_scheduler/app/main.py index 4d7b137..02afb34 100644 --- a/backend/task_scheduler/app/main.py +++ b/backend/task_scheduler/app/main.py @@ -411,7 +411,7 @@ async def _async_do_signin(account_id: str, cron_expr: str = ""): signed = already = failed = 0 log_entries = [] - async with httpx.AsyncClient(timeout=15, follow_redirects=True) as client: + async with httpx.AsyncClient(timeout=15, follow_redirects=False) as client: # 直接从 Cookie 获取 XSRF token,不访问首页 xsrf = cookies.get("XSRF-TOKEN", "") @@ -592,6 +592,11 @@ async def _do_single_signin(client, cookies: dict, topic: dict, xsrf: str) -> di }, headers=h, cookies=cookies, ) + + # 被重定向 = Cookie 失效 + if resp.status_code in (301, 302): + return {"status": "failed", "message": "签到API被重定向,Cookie可能失效"} + try: data = resp.json() except Exception: @@ -746,21 +751,23 @@ async def _build_daily_report() -> str: remain_days = (expire_dt - now).days expire_str = expire_dt.strftime("%m-%d") - # 真实 API 验证 + # 真实 API 验证(不跟随重定向,直接请求 AJAX API) real_valid = False try: - async with _httpx.AsyncClient(timeout=10, follow_redirects=True) as hc: + async with _httpx.AsyncClient(timeout=10, follow_redirects=False) as hc: vresp = await hc.get( "https://weibo.com/ajax/side/cards", params={"count": "1"}, - headers=WEIBO_HEADERS, + headers={**WEIBO_HEADERS, "X-Requested-With": "XMLHttpRequest"}, cookies=cookie_dict, ) - try: - vdata = vresp.json() - real_valid = vdata.get("ok") == 1 - except Exception: - real_valid = False + if vresp.status_code == 200: + try: + vdata = vresp.json() + real_valid = vdata.get("ok") == 1 + except Exception: + real_valid = False + # 302 = Cookie 失效 except Exception: real_valid = False