接口自动化:接口自动化中的公共鉴权设计
接口自动化做久了之后,你会发现最让人烦躁的失败,通常不是业务断言失败,而是鉴权失败。
典型症状是:
- token 过期导致一批 case 连续挂掉
- 测试环境和预发环境登录入口不一致
- 管理员和普通用户身份串用
- 签名算法改动后,几十条接口同时失效
- Jenkins 并发任务抢同一个共享账号,导致 session 混乱
如果公共鉴权没设计好,整套自动化看起来“覆盖很多”,实际每天都在被低价值失败拖垮。
一、为什么鉴权必须从 case 里剥离出来
这类坑在早期非常常见:在每个业务模块里自己处理登录和 header。
短期看很快,长期会出现三类问题:
- 登录逻辑散落各处,改一次要全局搜代码
- 多角色接口很容易串上下文
- 401、403、签名错误这些失败很难统一归类
所以后来会把鉴权设计成框架的基础设施,和日志、配置、报告一样独立治理。
二、真实项目里会遇到哪些鉴权类型
不是所有系统都只是 Bearer Token。在实际项目里,常见模式包括:
- 用户名密码换取 token
- cookie / session 登录
- JWT + refresh token
- 时间戳 + nonce + HMAC 签名
- 租户 ID + 用户 token 双重身份
- 白名单 IP + token 混合控制
这意味着公共鉴权不能写死成一个 get_token()。它更像一层可插拔 provider。
三、会用哪些工具和手段
如果还是 Python 执行层,通常会用:
requests.Session:处理 cookie / session 保持PyJWT或本地解析逻辑:判断 JWT 过期时间redis-py:做多任务共享凭证缓存hashlib/hmac:处理签名型接口threading.Lock或分布式锁:控制并发刷新
为什么需要 Redis:
- Jenkins 多任务并行时,单进程内存缓存不够用
- 巡检、回归、专项任务都可能共用同一套凭证体系
- 凭证共享以后,登录接口本身的压力会小很多
四、怎么拆鉴权模块
更常见的拆法是下面几层:
1 | auth/ |
职责划分是:
provider负责真正登录cache负责存 token / cookie / sessioncontext负责区分环境、角色、租户refresher负责未授权后的恢复动作manager对请求层暴露统一能力
这样后面认证方式变化时,不会把业务 case 一起拖着改。
五、一个更像真实项目的实现方式
以“管理后台 + 普通用户中心”并存的系统为例,会准备两组 provider:
AdminTokenProviderUserTokenProvider
然后在配置中定义:
1 | auth_profiles: |
业务 case 不直接写登录逻辑,只声明自己要哪种身份:
1 | headers = auth_manager.inject("buyer", env="pre") |
后面如果 buyer 这类身份从 token 换成 cookie session,业务 case 不需要跟着改。
六、失效恢复怎么做才不会制造噪声
很多自动化框架遇到 401 的处理方式非常粗暴:直接 fail。
不适合这么做。更合理的链路通常是:
- 第一次请求返回 401 或特定业务码
- 鉴权模块检查当前凭证是否接近过期
- 如果符合刷新条件,重新登录或刷新 token
- 原请求自动重放一次
- 若仍失败,将结果归类为“鉴权失败”而不是“业务失败”
这一步会直接影响告警质量。否则一次 token 过期,很可能触发几十条误报。
七、并发和多角色切换是最常见的隐藏问题
真正跑上 Jenkins 或平台后,两个问题最容易暴露:
1. 刷新风暴
同一时刻多个 worker 发现 token 过期,然后一起重新登录,导致认证服务压力升高,甚至把自己打挂。
解决方式通常是:
- 先查缓存中的过期时间
- 只有一个 worker 获得刷新锁
- 其余 worker 等待新 token 写回缓存
2. 角色污染
一个 suite 里管理员和普通用户混用,如果上下文存放不规范,很容易把管理员 token 带到普通接口里。
更稳妥的做法是:
- 凭证缓存 key 强制包含
env + role + tenant - 请求日志中打印当前身份标签
- 断言失败时把身份上下文一起输出到结果 JSON
这样出了问题,定位会快很多。
八、签名类接口怎么做统一封装
很多内部系统不是纯 token,而是:
- 当前时间戳
- 请求体摘要
- 固定密钥
- nonce
- 最后生成签名 header
这种场景如果放在业务 case 里手算,很快会失控。会把签名封装到 signer 中,由请求发送前统一注入。
比如:
1 | request = signer.sign(request, secret=secret_key) |
业务层只知道“这个接口需要 signed_auth”,不关心签名细节。
九、实现效果怎么判断
公共鉴权设计做完之后,会看这些结果:
- 登录接口抖动时,是否只影响少量任务,而不是拖垮整批 case
- 多角色场景下,是否还能保持上下文清晰
- 报告中能否把 401 / 403 / 签名错误单独分类
- 更换认证方式时,是否只修改 provider 层
- Jenkins 并发执行时,是否不再频繁出现凭证抢占问题
如果这些都没有改善,说明所谓公共鉴权很可能只是“把登录函数集中放了一个文件”。
十、结语
接口自动化中的公共鉴权,本质上是一个“身份基础设施”问题。它解决的不是怎么登录一次,而是怎么让多角色、多环境、多任务执行下的身份上下文长期稳定、可恢复、可归类。真正成熟的自动化框架,鉴权从来不是附属函数,而是核心底座。