共计 2230 个字符,预计需要花费 6 分钟才能阅读完成。
在移动端 App 开发和接口测试中,处理登录协议并提取 Token 是一个常见但容易出错的环节。很多开发者在这个环节会遇到各种问题,今天我就来分享一下我在实际项目中总结的 Token 提取经验。

背景痛点
首先,我们来看看为什么 Token 提取会成为一个难题。主要有三大典型问题:
- 动态加密:很多 App 现在会对 Token 进行动态加密,每次请求返回的 Token 格式可能都不一样
- 协议版本差异:同一个 App 的不同版本可能使用不同的协议格式,导致解析方法失效
- 响应结构变化:后端接口可能会在不通知的情况下改变响应结构,使得之前编写的解析代码无法工作
技术对比
提取 Token 常用的方法有三种,各有优缺点:
- 正则表达式:简单直接,但对复杂结构适应性差,容易因为格式变化而失效
- DOM 解析器(如 BeautifulSoup):适合 HTML 响应,对 JSON 支持不够友好
- 专用 HTTP 解析库(如 HTTPX):功能全面但学习成本较高
在实际项目中,我推荐使用 Python 的 requests 库配合少量正则表达式,这样既保证了灵活性又不会太复杂。
核心实现
下面我们来看一个完整的 Python 实现示例。这个例子涵盖了从登录请求到 Token 提取的全过程,包含必要的异常处理。
import requests
import re
from json import JSONDecodeError
# 模拟登录请求
try:
login_url = 'https://api.example.com/login'
payload = {'username': 'test', 'password': '123456'}
# 设置超时和重试
response = requests.post(login_url, json=payload, timeout=10)
response.raise_for_status() # 检查 HTTP 状态码
# 尝试从不同位置提取 Token
token = None
# 1. 检查响应头
if 'Authorization' in response.headers:
token = response.headers['Authorization'].split(' ')[-1]
# 2. 检查 Set-Cookie
if not token and 'session_token' in response.cookies:
token = response.cookies['session_token']
# 3. 检查响应体
if not token:
try:
data = response.json()
token = data.get('token') or data.get('access_token')
except JSONDecodeError:
# 如果不是 JSON,尝试正则匹配
match = re.search(r'token\":\"(.*?)\"', response.text)
if match:
token = match.group(1)
if not token:
raise ValueError('无法从响应中提取 Token')
print(f'成功获取 Token: {token[:10]}...') # 部分显示,避免泄露
except requests.exceptions.RequestException as e:
print(f'请求失败: {e}')
except ValueError as e:
print(f'Token 提取失败: {e}')
生产级考量
在实际生产环境中,我们还需要考虑更多细节:
- 自动重试机制:网络请求可能会失败,我们需要实现自动重试
- Token 有效性校验:使用 MD5 等校验和来验证 Token 格式是否正确
- 日志记录安全:确保日志中的敏感信息被适当脱敏
这里是一个改进版的生产环境示例:
import hashlib
from retrying import retry
# 自动重试装饰器
@retry(stop_max_attempt_number=3, wait_fixed=2000)
def get_token_with_retry():
# 同上登录代码
# ...
# 校验 Token 基本有效性
if token and len(token) < 10:
raise ValueError('Token 长度异常')
# 计算 Token 的 MD5 用于日志记录(不记录原始 Token)
token_md5 = hashlib.md5(token.encode()).hexdigest()
print(f'Token MD5: {token_md5}')
return token
避坑指南
根据我的经验,这里有三个常见的坑需要特别注意:
- iOS 端 Cookie 的 HttpOnly 标志:有些 App 会在 iOS 端设置 HttpOnly 的 Cookie,导致无法通过 JavaScript 读取
- Android 签名校验:Android 应用可能会对参数进行签名校验,直接模拟请求会失败
- Token 刷新机制:很多 Token 有有效期,需要处理自动刷新逻辑
延伸思考
如果你想更深入地验证 Token 提取的正确性,可以尝试使用 MitmProxy 进行动态抓包。这能让你看到 App 实际发送和接收的完整请求,对于调试非常有帮助。
总结
Token 提取看似简单,但实际上需要考虑很多细节。通过本文介绍的方法,你应该能够处理大多数 App 的登录协议。记住关键点:多位置检查、充分异常处理、生产环境安全考量。
完整的示例代码可以在 这个 Gist找到(注:链接为示例,实际不存在)。在实际项目中,你可能需要根据具体的 App 协议进行调整,但核心思路是不变的。
正文完
