您的 CaptchaAI API 密钥控制对您余额的访问。密钥泄露意味着未经授权的使用和资金的流失。本指南涵盖 IP 白名单、安全存储和访问控制。
API 密钥威胁
Exposed API key:
├── Leaked in Git repository
├── Hardcoded in client-side code
├── Shared in documentation
└── Visible in logs
Impact:
├── Balance drained by unauthorized users
├── Usage spikes from abuse
└── Key disabled by service provider
安全密钥存储
切勿对密钥进行硬编码
# BAD — key in source code
API_KEY = "abc123def456" # DO NOT DO THIS
# GOOD — environment variable
import os
API_KEY = os.environ["CAPTCHAAI_API_KEY"]
# GOOD — .env file (not committed to Git)
from dotenv import load_dotenv
load_dotenv()
API_KEY = os.environ["CAPTCHAAI_API_KEY"]
.env 文件
# .env (add to .gitignore!)
CAPTCHAAI_API_KEY=your_api_key_here
.gitignore
# Always ignore .env files
.env
.env.local
.env.production
基于环境的配置
import os
class CaptchaConfig:
"""Load CaptchaAI config from environment."""
def __init__(self):
self.api_key = os.environ.get("CAPTCHAAI_API_KEY")
if not self.api_key:
raise EnvironmentError(
"CAPTCHAAI_API_KEY not set. "
"Set it in your environment or .env file."
)
self.base_url = os.environ.get(
"CAPTCHAAI_URL", "https://ocr.captchaai.com"
)
def validate(self):
"""Verify the API key works."""
import requests
resp = requests.get(f"{self.base_url}/res.php", params={
"key": self.api_key,
"action": "getbalance",
"json": 1,
}, timeout=10)
data = resp.json()
if data.get("status") != 1:
raise RuntimeError(f"Invalid API key: {data.get('request')}")
return float(data["request"])
# Usage
config = CaptchaConfig()
balance = config.validate()
print(f"Key valid, balance: ${balance:.2f}")
按键轮换
定期轮换 API 密钥:
import os
import datetime
class KeyManager:
"""Manage API key rotation."""
def __init__(self):
self.primary_key = os.environ.get("CAPTCHAAI_API_KEY")
self.secondary_key = os.environ.get("CAPTCHAAI_API_KEY_BACKUP")
self.active_key = self.primary_key
def get_key(self):
return self.active_key
def rotate(self):
"""Switch to secondary key."""
if self.secondary_key:
self.active_key = self.secondary_key
print("Rotated to secondary key")
else:
print("No secondary key configured")
def test_key(self, key):
"""Verify a key is valid."""
import requests
resp = requests.get("https://ocr.captchaai.com/res.php", params={
"key": key, "action": "getbalance", "json": 1,
}, timeout=10)
return resp.json().get("status") == 1
# Usage
keys = KeyManager()
# If primary fails, rotate to secondary
if not keys.test_key(keys.get_key()):
keys.rotate()
请求验证
在发送之前验证请求以防止意外密钥泄露:
import requests
import logging
logger = logging.getLogger(__name__)
class SecureSolver:
"""Solver with security best practices."""
def __init__(self, api_key):
self.api_key = api_key
self.base = "https://ocr.captchaai.com"
def solve(self, method, **params):
# Validate inputs
self._validate_params(method, params)
data = {"key": self.api_key, "method": method, "json": 1}
data.update(params)
# Log without exposing key
logger.info(
"Submitting %s solve for %s",
method, params.get("pageurl", "unknown"),
)
resp = requests.post(
f"{self.base}/in.php", data=data, timeout=30,
)
return resp.json()
def _validate_params(self, method, params):
"""Prevent common security mistakes."""
# Ensure pageurl is a valid URL
pageurl = params.get("pageurl", "")
if pageurl and not pageurl.startswith(("http://", "https://")):
raise ValueError(f"Invalid pageurl: {pageurl}")
# Ensure method is valid
valid_methods = {
"userrecaptcha", "turnstile", "geetest",
"base64", "post", "bls", "cloudflare_challenge",
}
if method not in valid_methods:
raise ValueError(f"Unknown method: {method}")
不暴露密钥的日志记录
import logging
import re
logger = logging.getLogger(__name__)
class SafeFormatter(logging.Formatter):
"""Redact API keys from log messages."""
KEY_PATTERN = re.compile(r'[a-f0-9]{32}', re.IGNORECASE)
def format(self, record):
msg = super().format(record)
return self.KEY_PATTERN.sub("[REDACTED]", msg)
# Configure safe logging
handler = logging.StreamHandler()
handler.setFormatter(SafeFormatter("%(levelname)s: %(message)s"))
logger.addHandler(handler)
logger.setLevel(logging.INFO)
# Key is automatically redacted in logs
logger.info(f"Using key: abc123def456ghi789jkl012mno345pq")
# Output: INFO: Using key: [REDACTED]
Docker 的秘密
对于容器化部署:
# Dockerfile — DO NOT embed keys here
FROM python:3.11-slim
WORKDIR /app
COPY . .
RUN pip install requests
CMD ["python", "solver.py"]
# docker-compose.yml
services:
solver:
build: .
environment:
- CAPTCHAAI_API_KEY=${CAPTCHAAI_API_KEY}
# Or use Docker secrets:
secrets:
- captchaai_key
secrets:
captchaai_key:
file: ./secrets/captchaai_key.txt
CI/CD 安全
GitHub 操作
# .github/workflows/test.yml
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Run tests
env:
CAPTCHAAI_API_KEY: ${{ secrets.CAPTCHAAI_API_KEY }}
run: python test_solver.py
切勿在 CI 输出中记录或回显机密。
故障排除
| 问题 | 原因 | 处理方式 |
|---|---|---|
ERROR_WRONG_USER_KEY |
密钥不正确或已过期 | 从 CaptchaAI 仪表板验证密钥 |
| 意外余额耗尽 | 密钥泄露或共享 | 立即轮换密钥,审核访问 |
| 密钥在本地有效,但在 CI 中无效 | 环境变量未设置 | 添加到 CI/CD 秘密 |
| Git 历史记录中的密钥 | 提交的 .env 文件 | 旋转密钥,将.env添加到.gitignore,使用git filter-branch |
安全检查表
| 实践 | 地位 |
|---|---|
| 环境变量中的 API 密钥 | ✓ |
| .env 添加到 .gitignore | ✓ |
| 源代码中没有密钥 | ✓ |
| 日志中的密钥经过编辑 | ✓ |
| CI/CD 使用机密管理器 | ✓ |
| 钥匙轮换时间表 | ✓ |
| 平衡监控激活 | ✓ |
常问问题
如果我的 API 密钥泄露怎么办?
立即从 CaptchaAI 仪表板生成新密钥。使用旧密钥更新所有应用程序。检查您的余额是否未经授权使用。
我可以通过 IP 地址限制 API 密钥吗?
检查您的 CaptchaAI 仪表板的 IP 限制设置。如果可用,仅将您的服务器 IP 列入白名单,以防止未经授权的使用。
我应该使用不同的密钥进行开发和生产吗?
是的。对开发、登台和生产使用单独的密钥。如果开发密钥泄露,这会限制爆炸半径。
相关指南
保护您的投资——保护您的 CaptchaAI API 密钥今天。