Kasada 是互联网上最先进的机器人防护系统之一,被 Twitch、Kick、Nike 和 Arc'teryx 等网站使用。与 Cloudflare Turnstile 不同,很少有解决方案支持 Kasada — 网上几乎没有关于如何绕过它的文档。在本指南中,您将了解 Kasada 的工作原理、为什么难以绕过,以及如何使用 NSLSolver API 以编程方式解决它。
什么是 Kasada?
Kasada(前身为 Kasada IPS)是一个结合浏览器指纹识别和工作量证明(PoW)挑战的机器人防护平台。它旨在在边缘检测和阻止自动化流量,甚至在请求到达源服务器之前。
Kasada 保护着一些全球流量最大的平台:
- Twitch — 直播平台(登录、GQL API)
- Kick — 直播和实时内容平台
- Nike — 限量球鞋发售和产品页面
- Arc'teryx — 户外服装(结账和账户)
Kasada 防护的工作原理
当浏览器访问受 Kasada 保护的页面时,会发生以下流程:
- 页面从目标域名的唯一路径加载一个名为 p.js 的 JavaScript 文件。
- p.js 收集大量浏览器指纹 — canvas、WebGL、音频上下文、navigator 属性、屏幕尺寸、已安装字体等。
- 脚本生成工作量证明解决方案(一个计算密集型哈希挑战),以证明客户端是真实浏览器。
- 指纹和 PoW 结果被打包成 x-kpsdk-ct(客户端令牌)、x-kpsdk-cd(挑战数据)、x-kpsdk-v(版本)和 x-kpsdk-h(硬件哈希)请求头。
对受保护 API 的每个后续请求都必须包含这些有效且未过期的请求头。否则,服务器会返回 429 或重定向到挑战页面。
为什么 Kasada 难以绕过
Kasada 比大多数验证码系统难绕过得多:
- !重度浏览器指纹识别 — Kasada 收集 50 多个浏览器信号,并与已知浏览器配置文件进行比较。无头浏览器和伪造的用户代理会被立即检测到。
- !工作量证明挑战 — PoW 组件需要真实的计算工作,防止简单的重放攻击,并增加暴力破解的延迟。
- !频繁更新 — Kasada 定期更改其检测方法、指纹收集和 p.js 混淆。今天有效的解决方案明天可能失效。
- !很少有解决方案支持它 — 大多数验证码解决服务(2Captcha、Anti-Captcha、CapSolver)根本不提供 Kasada 解决,使其成为最难绕过的防护之一。
解决方案:NSLSolver Kasada API
NSLSolver 在服务端处理整个 Kasada 挑战流程。您发送目标 URL 和配置,我们返回您需要的 x-kpsdk 请求头:
- 无需浏览器 — 我们在基础设施上解决挑战,只返回请求头。
- 始终保持最新 — 我们监控 Kasada 的变化并自动更新解决器。
- 简单的 REST API — 一个 POST 请求,几秒钟内获取请求头。
第一步:安装 Python SDK
从 PyPI 安装官方 NSLSolver Python SDK:
第二步:了解参数
Kasada 解决需要比简单验证码更多的参数。您需要检查目标网站的网络流量来找到这些值:
| 参数 | 必填 | 说明 |
|---|---|---|
| url | Yes | 受 Kasada 保护页面的完整 URL |
| user_agent | Yes | 浏览器的 User-Agent 字符串 — 后续请求中必须完全匹配 |
| ua_version | Yes | User-Agent 中的 Chrome 主版本号(例如 145) |
| kasada_config.p_js_path | Yes | Kasada p.js 脚本的路径 — 在浏览器的网络标签中查找 |
| kasada_config.fp_host | Yes | 提供 Kasada 指纹页面的主机名(通常是登录域名) |
| kasada_config.tl_host | Yes | Kasada TL 令牌端点的主机名(通常是 API 域名) |
第三步:解决 Kasada 挑战
使用 NSLSolver SDK 和 KasadaConfig 解决挑战。以下是 Twitch 示例:
from nslsolver import NSLSolver, KasadaConfig
solver = NSLSolver("nsl_YOUR_API_KEY")
result = solver.solve_kasada(
url="https://passport.twitch.tv",
user_agent="Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36",
ua_version=145,
kasada_config=KasadaConfig(
p_js_path="/149e9513-01fa-4fb0-aad4-566afd725d1b/2d206a39-8ed7-437e-a3be-862e0f06eea3/p.js",
fp_host="passport.twitch.tv",
tl_host="gql.twitch.tv"
)
)
print(result.headers)API 返回您需要的已解决 x-kpsdk 请求头:
{
"success": true,
"headers": {
"x-kpsdk-ct": "eyJ0eXAi...a_long_token",
"x-kpsdk-cd": "AQAAAJY...proof_of_work_solution",
"x-kpsdk-v": "j-0.0.0",
"x-kpsdk-h": "SW50ZWw...browser_hash"
},
"cost": 0.002
}第四步:在请求中使用请求头
将返回的请求头附加到对受保护 API 的请求中。确保 User-Agent 与您传递给解决器的完全匹配:
import requests
# After solving Kasada with NSLSolver:
kasada_headers = result.headers
# Make your request with the solved headers
response = requests.post(
"https://gql.twitch.tv/gql",
headers={
"x-kpsdk-ct": kasada_headers["x-kpsdk-ct"],
"x-kpsdk-cd": kasada_headers["x-kpsdk-cd"],
"x-kpsdk-v": kasada_headers["x-kpsdk-v"],
"x-kpsdk-h": kasada_headers["x-kpsdk-h"],
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36",
"Content-Type": "application/json"
},
json={"query": "..."}
)
print(response.status_code)完整示例(含错误处理)
以下是适用于生产环境的示例,包含重试和错误处理:
from nslsolver import NSLSolver, KasadaConfig
import requests
import time
API_KEY = "nsl_YOUR_API_KEY"
TARGET_URL = "https://passport.twitch.tv"
USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/145.0.0.0 Safari/537.36"
def solve_kasada(retries=3):
"""Solve Kasada challenge via NSLSolver Python SDK."""
solver = NSLSolver(API_KEY)
for attempt in range(retries):
try:
result = solver.solve_kasada(
url=TARGET_URL,
user_agent=USER_AGENT,
ua_version=145,
kasada_config=KasadaConfig(
p_js_path="/149e9513-01fa-4fb0-aad4-566afd725d1b/2d206a39-8ed7-437e-a3be-862e0f06eea3/p.js",
fp_host="passport.twitch.tv",
tl_host="gql.twitch.tv"
)
)
if result.success:
return result.headers
print(f"Attempt {attempt + 1} failed")
except Exception as e:
print(f"Error: {e}")
if attempt < retries - 1:
time.sleep(3)
return None
# Solve and use the headers
headers = solve_kasada()
if headers:
print("Got Kasada headers, making request...")
resp = requests.post(
"https://gql.twitch.tv/gql",
headers={
**headers,
"User-Agent": USER_AGENT,
"Content-Type": "application/json"
},
json={"query": "..."}
)
print(f"Status: {resp.status_code}")
else:
print("Failed to solve Kasada after retries.")定价与性能
Kasada 解决按次计费,反映了 PoW 挑战的计算成本:
- $每 1,000 次解决 $1.50 — 仅对成功的解决收费
- ~平均解决时间 3-10 秒 — PoW 挑战比简单验证码耗时更长
- %90%+ 成功率 — 我们持续监控并适应 Kasada 的频繁更新
重要提示:您传递给 NSLSolver 的 User-Agent 必须与您在后续请求中使用的 User-Agent 完全匹配。Kasada 会将此请求头与指纹进行验证 — 不匹配将导致立即被封。