From dccfae522716f83b5bb2be68639713bc833f4b92 Mon Sep 17 00:00:00 2001 From: Jeason <1710884619@qq.com> Date: Thu, 9 Apr 2026 08:59:46 +0800 Subject: [PATCH] =?UTF-8?q?=E6=97=A5=E6=8A=A5=E5=A2=9E=E5=8A=A0Cookie?= =?UTF-8?q?=E6=9C=89=E6=95=88=E6=9C=9F=E6=A3=80=E6=B5=8B(ALF=E5=AD=97?= =?UTF-8?q?=E6=AE=B5),=20=E6=8C=89=E5=89=A9=E4=BD=99=E5=A4=A9=E6=95=B0?= =?UTF-8?q?=E5=88=86=E7=BA=A7=E9=A2=84=E8=AD=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/task_scheduler/app/main.py | 63 ++++++++++++++++++++++-------- test_fetch_topics.py | 15 +++++++ 2 files changed, 62 insertions(+), 16 deletions(-) diff --git a/backend/task_scheduler/app/main.py b/backend/task_scheduler/app/main.py index 720115f..1446162 100644 --- a/backend/task_scheduler/app/main.py +++ b/backend/task_scheduler/app/main.py @@ -651,6 +651,7 @@ async def _build_daily_report() -> str: from shared.models.account import Account from shared.models.signin_log import SigninLog from shared.models.user import User + from shared.crypto import decrypt_cookie, derive_key today_start = datetime.now().replace(hour=0, minute=0, second=0, microsecond=0) now = datetime.now() @@ -729,19 +730,37 @@ async def _build_daily_report() -> str: if msg: rank_details.append({"name": name, "topic": topic, "message": msg}) - # 4. Cookie 即将失效的账号(超过 3 天未检查) - stale_cutoff = now - timedelta(days=3) - stale_result = await session.execute( - select(Account.remark, Account.weibo_user_id, Account.last_checked_at) - .where(Account.status == "active") - .where( - (Account.last_checked_at < stale_cutoff) | (Account.last_checked_at == None) - ) + # 4. Cookie 过期时间检测(从 ALF 字段解析) + cookie_expiry = [] + all_accounts_result = await session.execute( + select(Account.id, Account.remark, Account.weibo_user_id, + Account.encrypted_cookies, Account.iv, Account.status) + .where(Account.status.in_(["active", "pending"])) ) - stale_accounts = [ - (row[0] or row[1], row[2].strftime("%m-%d %H:%M") if row[2] else "从未") - for row in stale_result.all() - ] + key = derive_key(shared_settings.COOKIE_ENCRYPTION_KEY) + for acc_row in all_accounts_result.all(): + acc_id, remark, uid, enc_cookies, iv, status = acc_row + name = remark or uid + try: + cookie_str = decrypt_cookie(enc_cookies, iv, key) + alf = "" + for pair in cookie_str.split(";"): + pair = pair.strip() + if pair.startswith("ALF="): + alf = pair.split("=", 1)[1].strip() + break + if alf and alf.isdigit(): + expire_dt = datetime.fromtimestamp(int(alf)) + remain_days = (expire_dt - now).days + cookie_expiry.append({ + "name": name, + "expire": expire_dt.strftime("%m-%d"), + "remain": remain_days, + }) + else: + cookie_expiry.append({"name": name, "expire": "未知", "remain": -1}) + except Exception: + cookie_expiry.append({"name": name, "expire": "解密失败", "remain": -1}) finally: await eng.dispose() @@ -777,10 +796,22 @@ async def _build_daily_report() -> str: for r in rank_details: lines.append(f" {r['name']} - {r['topic']}: {r['message']}") - if stale_accounts: - lines += ["", "⚠️ 需要关注"] - for name, last in stale_accounts: - lines.append(f" {name} (上次检查: {last})") + if cookie_expiry: + lines += ["", "🍪 Cookie 有效期"] + expiring_soon = [] + for ce in cookie_expiry: + remain = ce["remain"] + if remain < 0: + lines.append(f" ⚠️ {ce['name']}: {ce['expire']}") + elif remain <= 3: + lines.append(f" 🔴 {ce['name']}: {ce['expire']} (剩 {remain} 天,即将过期!)") + expiring_soon.append(ce["name"]) + elif remain <= 7: + lines.append(f" 🟡 {ce['name']}: {ce['expire']} (剩 {remain} 天)") + else: + lines.append(f" 🟢 {ce['name']}: {ce['expire']} (剩 {remain} 天)") + if expiring_soon: + lines.append(f" ⚠️ 请尽快重新扫码: {', '.join(expiring_soon)}") if total_logs == 0: lines += ["", "💤 今日暂无签到记录"] diff --git a/test_fetch_topics.py b/test_fetch_topics.py index 8db81a7..bb9f072 100644 --- a/test_fetch_topics.py +++ b/test_fetch_topics.py @@ -12,6 +12,11 @@ import re import asyncio sys.path.insert(0, os.path.join(os.path.dirname(__file__), "backend")) +sys.path.insert(0, os.path.join(os.path.dirname(__file__))) + +# 兼容容器内运行(/app 目录) +if os.path.exists("/app/shared"): + sys.path.insert(0, "/app") from shared.config import shared_settings from shared.crypto import decrypt_cookie, derive_key @@ -56,6 +61,16 @@ async def main(): print(f"🍪 Cookie 数量: {len(cookies)}, keys: {list(cookies.keys())}") + # 检查 Cookie 有效期 + from datetime import datetime + alf = cookies.get("ALF", "") + if alf and alf.isdigit(): + expire_time = datetime.fromtimestamp(int(alf)) + remain = (expire_time - datetime.now()).days + print(f"📅 Cookie 过期时间: {expire_time.strftime('%Y-%m-%d %H:%M:%S')} (还剩 {remain} 天)") + else: + print(f"📅 ALF 字段: {alf or '无'} (无法判断过期时间)") + await engine.dispose() # 测试 1: 访问 weibo.com