适用场景:为什么需要浏览器指纹风控
在Web反爬虫、反欺诈、账户安全等领域,单纯依赖IP或Cookie已无法有效识别自动化工具。浏览器指纹通过采集navigator、screen、canvas、WebGL等20+维度的特征,生成设备唯一标识,并结合规则引擎输出风险评分,精准检测Headless Chrome、Selenium、Puppeteer、Playwright等异常环境。
本文聚焦最小可运行示例,即用最少的参数和代码快速验证接口能力,帮助开发者在不依赖前端SDK的情况下,先通过curl或Python脚本调用,理解输入输出后再进行正式集成。
接口能力边界
- 接口地址:
POST https://v1.apizero.cn/api/browser-fingerprint - 请求方法:POST
- Content-Type:
application/json - 核心能力:接收UA、平台、语言、时区、屏幕分辨率、颜色深度、像素比、硬件并发数、设备内存、插件列表、Canvas指纹、WebGL渲染器、字体列表、WebDriver标记等字段,综合9类规则输出风险评分(0-100)与等级(safe/low/medium/high/critical)、命中的风险因子及异常项。
- QPS上限:5次/秒(以文档为准)
注意:接口仅处理服务端计算,前端采集SDK需自行实现。本文示例使用手动构造的JSON模拟采集数据。
请求参数与鉴权
鉴权方式
请求头中需携带API密钥,支持两种方式(推荐使用X-API-Key):
| Header | 必填 | 说明 |
|---|---|---|
X-API-Key | 是 | 在平台获取的密钥,如sk-xxxx |
Content-Type | 是 | application/json |
Authorization | 否 | 备用鉴权,以文档为准 |
请求字段说明
以下为JSON Body中的主要字段(完整字段列表见官方文档):
| 字段名 | 类型 | 必填 | 说明与示例 |
|---|---|---|---|
ua | string | 是 | navigator.userAgent,如"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 ..." |
platform | string | 否 | navigator.platform,如"Win32" |
language | string | 否 | 主语言代码,如"zh-CN" |
timezone | string | 否 | IANA时区,如"Asia/Shanghai" |
timezoneOffset | number | 否 | getTimezoneOffset() 返回值(分钟),如-480 |
screenWidth | number | 否 | 屏幕宽度,如1920 |
screenHeight | number | 否 | 屏幕高度,如1080 |
colorDepth | number | 否 | 色彩深度,如24 |
pixelRatio | number | 否 | 设备像素比,如1.25 |
hardwareConcurrency | number | 否 | 逻辑CPU核心数,如8 |
deviceMemory | number | 否 | 设备内存(GB),如8 |
plugins | array | 否 | 插件列表,每个元素含name、description等 |
canvas | string | 否 | Canvas指纹(Base64),参考前端SDK采集 |
webgl | string | 否 | WebGL指纹(Base64) |
fonts | array | 否 | 系统字体列表,如["Arial", "Microsoft YaHei"] |
webdriver | boolean | 否 | navigator.webdriver值,正常为false |
必填字段仅为
ua,但字段越多,风险判断越准确。推荐至少提供ua、platform、language、screenWidth/screenHeight、hardwareConcurrency、webdriver。
最小可运行curl示例
以下示例仅包含必填字段ua,适合快速测试接口连通性(请将$APIZERO_API_KEY替换为真实密钥):
curl -sS \ -X POST \ -H "X-API-Key: $APIZERO_API_KEY" \ -H "Content-Type: application/json" \ -d '{"ua": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36"}' \ "https://v1.apizero.cn/api/browser-fingerprint"若希望得到更丰富的检测结果,可构造包含常见自动化标记的请求体(模拟Headless Chrome):
curl -sS \ -X POST \ -H "X-API-Key: $APIZERO_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "ua": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) HeadlessChrome/125.0.0.0 Safari/537.36", "platform": "Linux x86_64", "language": "en-US", "timezone": "UTC", "timezoneOffset": 0, "screenWidth": 1920, "screenHeight": 1080, "colorDepth": 24, "pixelRatio": 1, "hardwareConcurrency": 2, "deviceMemory": 2, "webdriver": true, "fonts": ["Arial", "Courier New"], "plugins": [] }' \ "https://v1.apizero.cn/api/browser-fingerprint"Python代码接入示例
以下使用requests库封装函数,便于集成到爬虫或风控系统中:
import requests import json def analyze_browser_fingerprint(api_key, fingerprint_data): """ 浏览器指纹风控分析 :param api_key: API密钥 :param fingerprint_data: dict,至少包含'ua'字段 :return: dict 响应数据 """ url = "https://v1.apizero.cn/api/browser-fingerprint" headers = { "X-API-Key": api_key, "Content-Type": "application/json" } resp = requests.post(url, headers=headers, json=fingerprint_data, timeout=10) resp.raise_for_status() return resp.json() # 使用示例 api_key = "sk-your-key-here" payload = { "ua": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/125.0.0.0 Safari/537.36", "platform": "MacIntel", "language": "zh-CN", "timezone": "Asia/Shanghai", "screenWidth": 1440, "screenHeight": 900, "hardwareConcurrency": 8, "webdriver": False } try: result = analyze_browser_fingerprint(api_key, payload) print(json.dumps(result, indent=2, ensure_ascii=False)) except Exception as e: print(f"调用失败: {e}")返回值解读
成功响应HTTP状态码200,Body为JSON,结构如下:
{ "code": 0, "msg": "成功", "request_id": "abc123", "data": { "fingerprint_id": "a1b2c3d4e5f6...", "risk": 72, "risk_label": "高风险", "risk_level": "high", "timestamp": 1715097600, "factors": [ { "name": "webdriver", "desc": "WebDriver 标记为 true", "score": 30 }, { "name": "virtual_gpu", "desc": "WebGL 渲染器包含虚拟/软渲染特征: SwiftShader", "score": 15 } ], "anomalies": [ "UA 声称 Windows 但 platform 不匹配" ], "device_profile": { "browser": "Chrome 125", "os": "Windows", "device_type": "Desktop", "screen": "1920x1080", "cores": 8, "memory": "8GB", "fonts_count": 42, "plugins_count": 3, "gpu": "ANGLE (NVIDIA, GeForce RTX 3060)", "touch": false } } }核心字段说明
| 字段路径 | 类型 | 说明 |
|---|---|---|
code | int | 业务状态码,0表示成功,非0表示异常 |
msg | string | 状态描述 |
request_id | string | 本次请求唯一标识,用于排查 |
data.fingerprint_id | string | 生成的设备指纹ID |
data.risk | int | 风险评分 0-100,越高越危险 |
data.risk_level | string | 等级:safe(0-20)、low(21-40)、medium(41-60)、high(61-80)、critical(81-100) |
data.risk_label | string | 中文标签,如“高风险” |
data.timestamp | int | Unix时间戳 |
data.factors | array | 命中的风险因子列表,每项含名称、描述和贡献分数 |
data.anomalies | array | 异常项描述,如UA与平台不匹配 |
data.device_profile | object | 设备画像概览,方便快速了解设备特征 |
应用场景:根据risk_level决定是否拦截。例如high或critical可触发验证码、拒绝访问或提高验证强度。factors列表可帮助安全团队定位具体风险来源。
常见错误与排查
| HTTP状态码 | 可能原因 | 排查方法 |
|---|---|---|
| 400 | 请求体格式错误或缺少必填字段ua | 检查JSON是否合法,ua是否存在 |
| 401 | API密钥无效或未提供 | 确认X-API-Key头是否正确,密钥是否过期 |
| 429 | QPS超限(超过5次/秒) | 降低请求频率,加入重试机制 |
| 500 | 服务端内部错误 | 稍后重试,或提供request_id联系支持 |
200但code != 0 | 业务逻辑错误 | 根据msg字段定位,常见如字段类型不匹配 |
字段校验常见问题:
timezoneOffset需为数字(分钟),负数表示UTC+时区(因为getTimezoneOffset()返回UTC-本地,如中国为-480);plugins需为数组,每个元素至少含name字符串;fonts应为字符串数组;webdriver需为布尔值,传入"true"字符串会导致类型错误。
工程化注意事项
- QPS控制:官方限频5次/秒,并发场景下需加入令牌桶或请求队列。如果业务量较大,建议批量采集后异步调用,或使用代理池分散请求。
- 字段完整性:虽然仅
ua必填,但实际指纹识别依赖多维度交叉验证。至少提供10个以上字段可显著提升准确率。前端SDK采集时注意保护用户隐私,避免采集超出需要的字段。 - 缓存策略:对于同一指纹ID(
fingerprint_id),风险等级在短时间(如5分钟)内通常不会剧烈变化,可设置本地缓存减少重复调用。 - 异常重试:网络抖动或服务端偶发错误时,采用指数退避重试(如1s、2s、4s),最大重试3次。注意区分可重试(5xx、超时)和不可重试(4xx鉴权、参数错误)。
- 数据安全:API密钥不要硬编码在客户端代码或版本控制中,建议通过环境变量或配置中心注入。
- 生产集成:在业务侧,将指纹分析作为异步非关键路径(如发送消息到队列)处理,避免阻塞用户登录或下单流程。
参考文档
- 浏览器指纹风控API官方文档
- 原始Markdown文档
本文基于API事实卡写作,所有接口地址、参数、返回结构均以官方文档为准。若字段或QPS有更新,请参考最新文档。