title: Full-Link Automation: Leyifan Auto-Login & API Reverse Engineering date: 2026-02-09 tags: - Python - RESTful API - Auto-Login - Debugging categories: - Engineering Log
全链路逆向:乐淘一番(Leyifan) 从非标准接口到自动登录的演进
摘要 (Abstract)
本文记录了针对乐淘一番(Leyifan)移动端 H5 站点的自动化签到脚本开发过程。
项目经历了三个阶段的迭代: * V1.0:解决了后端非标准的 HTTP Method 与 500 状态码逻辑(手动 Token)。 * V2.0:突破了 Token 短生命周期(TTL)限制,实现了账号密码自动换取 Token。 * V2.2:修正了前后端域名分离导致的 404 路由错误,最终实现了完全无人值守。
1. 协议侦查 (Reconnaissance)
1.1 鉴权机制与 TTL 限制
初始分析发现,该站点采用 Authori-zation(非标准拼写)Header 进行鉴权。
但在实际运行中发现,该 Token 的生命周期(Time To Live)极短,不到 24 小时即失效。这意味着 V1.0 版本中“手动抓包填入 Token”的方案无法长期稳定运行。
1.2 接口混淆 (Ambiguity)
在流量审计中,发现了三个命名极度相似的接口,极易造成误判:
- GET
/api/front/user: 返回isDaySign: true。这是状态查询接口。 - GET
/api/front/user/integral: 返回积分历史记录。这是日志查询接口。 - GET
/api/front/user/sign/integral: 返回message: "操作成功"。这才是真正的动作触发接口。
2. 迭代过程:V1.0 (手动方案的失败)
2.1 遇到的非标准设计
- Method 误判:涉及数据修改的操作通常使用 POST,但该站点强制使用 GET,否则返回 405。
- 500 状态码:后端将“今日已签到”的业务逻辑冲突,直接抛出为
500 Server Error。
2.2 [已作废] V1.0 核心代码遗迹
由于 Token 频繁过期,以下依赖手动填写 Token 的逻辑已被完全废弃。
V1.0 Legacy Code (Deprecated)
该版本方案不可持续,仅作逻辑分析留档。
- import requests
- import time
-
- # ================= 配置区 =================
- # [DEPRECATED] Manual Token Injection
- tokens = [
- "9dd9844f12ec4f30xxxxxxxx",
- "c99047c49fxxxxxxxxxxxxxx"
- ]
-
- def run_leyifan_sign(token, index):
- # [BUG] V1 used the Frontend Host, not API Host
- url = "[https://mall.leyifan.com/api/front/user/sign/integral](https://mall.leyifan.com/api/front/user/sign/integral)"
-
- headers = {
- "Authori-zation": token, # Token expires every few hours
- "Appplatform": "other",
- "User-Agent": "Mozilla/5.0 ...",
- "platform": "h5"
- }
-
- try:
- # [Correction] Must use GET, POST returns 405
- response = requests.post(url, headers=headers, json={})
-
- if response.status_code == 200:
- print(f"✅ Success")
- elif response.status_code == 500:
- # Logic: 500 implies duplicate check-in
- print(f"⚠️ Already checked in.")
-
- except Exception as e:
- print(f"❌ Error: {e}")
3. 迭代过程:V2.0 (自动登录突破)
为了解决 Token 过期问题,我们将目标转向逆向登录接口。
3.1 跨域 SSO 发现
通过观察,发现乐淘一番(子站)与乐一番转运(主站)存在账户关联。我们捕获到了关键的登录接口:
* Endpoint: POST /api/front/login/leyifan
* Payload: 包含主站的 account 与 password。
* Response: 直接返回子站的有效 Token。
这一发现意味着我们可以绕过复杂的主站跳转,直接通过 API 交换凭证。
4. 迭代过程:V2.2 (域名修正与最终版)
在集成自动登录后,脚本曾短暂遭遇 404 Not Found 错误。
4.1 根本原因分析 (Root Cause)
脚本 V2.0 错误地使用了前端页面域名来拼接 API 路径。
* ❌ Frontend Host: letaoyifan.com (用户访问的 Web 页面,不处理 API)
* ✅ API Host: api.mall.leyifan.cn (实际后端主机)
4.2 最终实现 (Implementation)
修正 Host 指向后,系统实现了全链路闭环。
点击展开:Leyifan 全自动签到脚本 V2.2 (Final)
import requests
import time
import random
# ================= Configuration =================
# ⚠️ 敏感信息请通过环境变量注入,勿硬编码上传
accounts = [
("user1@email.com", "pass******"),
("user2@email.com", "pass******")
]
# ================= Core Logic =================
def login_and_get_token(email, password, index):
print(f"🔐 [Account {index}] Auto-login attempt...")
# [Discovery] The dedicated login endpoint
login_url = "[https://api.mall.leyifan.cn/api/front/login/leyifan](https://api.mall.leyifan.cn/api/front/login/leyifan)"
headers = {
"Content-Type": "application/json;charset=UTF-8",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)...",
"Origin": "[https://letaoyifan.com](https://letaoyifan.com)", # Spoofing origin
"Referer": "[https://letaoyifan.com/](https://letaoyifan.com/)"
}
try:
resp = requests.post(login_url, json={"account": email, "password": password}, headers=headers)
data = resp.json()
if data.get("code") == 200:
token = data["data"]["token"]
print(f"✅ [Account {index}] Token Refreshed.")
return token
except Exception as e:
print(f"❌ [Account {index}] Login Failed: {e}")
return None
def sign_in(token, index):
print(f"🚀 [Account {index}] Executing Sign-in...")
# [Fix] Correct API Domain: api.mall.leyifan.cn
sign_url = "[https://api.mall.leyifan.cn/api/front/user/sign/integral](https://api.mall.leyifan.cn/api/front/user/sign/integral)"
headers = {
"Authori-zation": token, # Injected dynamic token
"User-Agent": "Mozilla/5.0 ...",
"Origin": "[https://letaoyifan.com](https://letaoyifan.com)"
}
try:
# [Fix] Method must be GET
resp = requests.get(sign_url, headers=headers)
# [Logic] Handling Non-standard 500 Error
if resp.status_code == 200 and "成功" in resp.text:
print(f"✅ [Account {index}] Success!")
elif resp.status_code == 500 and "已签到" in resp.text:
print(f"⚠️ [Account {index}] Already checked in (Idempotency confirmed).")
else:
print(f"❌ [Account {index}] Error: {resp.status_code}")
except Exception as e:
print(f"❌ Connection Error: {e}")
# ... (Main Loop Omitted)
5. 总结 (Conclusion)
本次工程实践不仅解决了单一接口的自动化问题,更完整复盘了从 流量嗅探 -> 逻辑修正 -> 架构升级 的全过程。
关键技术沉淀: 1. 动态鉴权:不再依赖静态 Token,通过模拟登录接口实现了 Session 的永久保活。 2. 环境隔离认知:精准区分了 Frontend Host 与 API Host,解决了跨域 API 调用的 404 陷阱。 3. 容错设计:建立了针对非标准状态码(500/405)的防御性处理机制。
该方案目前已稳定运行,无需人工干预。
Generated by Engineering Log System v2.2