216 lines
5.0 KiB
Markdown
216 lines
5.0 KiB
Markdown
|
|
# OpenClaw Auth Runtime Python 实现
|
|||
|
|
|
|||
|
|
基于 `~/clawd/skills/_shared/auth-runtime` 的 TypeScript 实现,提供 Python 版本的客户端密钥认证。
|
|||
|
|
|
|||
|
|
## 功能特性
|
|||
|
|
|
|||
|
|
- ✅ 使用 CLIENT_KEY 获取访问令牌
|
|||
|
|
- ✅ 支持令牌缓存(可配置 TTL)
|
|||
|
|
- ✅ 自动刷新过期令牌
|
|||
|
|
- ✅ 401/403 自动重试
|
|||
|
|
- ✅ 从 .env 文件自动加载配置
|
|||
|
|
|
|||
|
|
## 快速开始
|
|||
|
|
|
|||
|
|
### 1. 配置环境变量
|
|||
|
|
|
|||
|
|
在 `.env` 文件中设置 CLIENT_KEY:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
# 从 ~/clawd/skills/_shared 获取 CLIENT_KEY
|
|||
|
|
CLIENT_KEY=your-client-key-here
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 获取访问令牌
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
from auth_runtime import create_env_config, get_access_token
|
|||
|
|
|
|||
|
|
# 创建配置(自动从环境变量加载)
|
|||
|
|
config = create_env_config()
|
|||
|
|
|
|||
|
|
# 获取访问令牌(带缓存)
|
|||
|
|
token = get_access_token(dry_run=False, config=config)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 发送 API 请求
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
from auth_runtime import request_api_with_auto_refresh
|
|||
|
|
|
|||
|
|
# 发送请求(自动处理令牌刷新)
|
|||
|
|
response = request_api_with_auto_refresh(
|
|||
|
|
method="POST",
|
|||
|
|
url="https://api-gw-test.yuanwei-lnc.com/your-api-endpoint",
|
|||
|
|
dry_run=False,
|
|||
|
|
config=config,
|
|||
|
|
body={"key": "value"},
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
print(f"状态码:{response.status}")
|
|||
|
|
print(f"响应体:{response.body}")
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## API 参考
|
|||
|
|
|
|||
|
|
### 配置
|
|||
|
|
|
|||
|
|
#### `create_env_config() -> EnvConfig`
|
|||
|
|
|
|||
|
|
从环境变量创建配置:
|
|||
|
|
|
|||
|
|
| 环境变量 | 默认值 | 说明 |
|
|||
|
|
|---------|--------|------|
|
|||
|
|
| `AUTH_BASE` | `https://api-gw-test.yuanwei-lnc.com` | 认证基础 URL |
|
|||
|
|
| `CLIENT_KEY` | **必需** | 客户端密钥 |
|
|||
|
|
| `AUTH_CACHE_DIR` | `/tmp/skill-auth-cache` | 缓存目录 |
|
|||
|
|
| `AUTH_MIN_TTL_SEC` | `60` | 最小令牌 TTL(秒) |
|
|||
|
|
|
|||
|
|
### 令牌管理
|
|||
|
|
|
|||
|
|
#### `get_access_token(dry_run, config) -> str`
|
|||
|
|
|
|||
|
|
获取访问令牌(带缓存):
|
|||
|
|
1. 检查缓存
|
|||
|
|
2. 如果缓存有效,返回缓存令牌
|
|||
|
|
3. 否则请求新令牌并缓存
|
|||
|
|
|
|||
|
|
#### `refresh_access_token(dry_run, config) -> str`
|
|||
|
|
|
|||
|
|
刷新访问令牌(绕过缓存)
|
|||
|
|
|
|||
|
|
### API 请求
|
|||
|
|
|
|||
|
|
#### `request_api(method, url, auth_token, body) -> ApiResponse`
|
|||
|
|
|
|||
|
|
发送 HTTP 请求
|
|||
|
|
|
|||
|
|
#### `request_api_with_auto_refresh(method, url, dry_run, config, body) -> ApiResponse`
|
|||
|
|
|
|||
|
|
发送 API 请求并自动刷新令牌:
|
|||
|
|
1. 使用当前令牌发送请求
|
|||
|
|
2. 如果是 401/403 错误,刷新令牌并重试一次
|
|||
|
|
|
|||
|
|
### 便捷函数
|
|||
|
|
|
|||
|
|
#### `load_client_key_from_env(env_path) -> str`
|
|||
|
|
|
|||
|
|
从 .env 文件加载 CLIENT_KEY
|
|||
|
|
|
|||
|
|
优先级:
|
|||
|
|
1. 环境变量 `CLIENT_KEY`
|
|||
|
|
2. .env 文件中的 `CLIENT_KEY`
|
|||
|
|
3. 抛出异常
|
|||
|
|
|
|||
|
|
## 使用示例
|
|||
|
|
|
|||
|
|
### 示例 1: 简单的 API 调用
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
from auth_runtime import create_env_config, request_api_with_auto_refresh
|
|||
|
|
|
|||
|
|
config = create_env_config()
|
|||
|
|
|
|||
|
|
response = request_api_with_auto_refresh(
|
|||
|
|
method="POST",
|
|||
|
|
url=f"{config.auth_base}/your-endpoint",
|
|||
|
|
dry_run=False,
|
|||
|
|
config=config,
|
|||
|
|
body={"url": "https://example.com"},
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
if response.status == 200:
|
|||
|
|
print("成功:", response.body)
|
|||
|
|
else:
|
|||
|
|
print("失败:", response.status, response.body)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 示例 2: 结合 Excel 翻译使用
|
|||
|
|
|
|||
|
|
```python
|
|||
|
|
from auth_runtime import create_env_config, request_api_with_auto_refresh
|
|||
|
|
import json
|
|||
|
|
|
|||
|
|
config = create_env_config()
|
|||
|
|
|
|||
|
|
# 调用 1688 API 获取商品详情
|
|||
|
|
response = request_api_with_auto_refresh(
|
|||
|
|
method="POST",
|
|||
|
|
url=f"{config.auth_base}/ecom/tasks/scrape",
|
|||
|
|
dry_run=False,
|
|||
|
|
config=config,
|
|||
|
|
body={"url": "https://detail.1688.com/offer/123.html"},
|
|||
|
|
)
|
|||
|
|
|
|||
|
|
if response.status == 200:
|
|||
|
|
data = json.loads(response.body)
|
|||
|
|
print("商品价格:", data["price"])
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 缓存机制
|
|||
|
|
|
|||
|
|
令牌缓存位置:`/tmp/skill-auth-cache/token_<hash>.json`
|
|||
|
|
|
|||
|
|
缓存文件内容:
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"access_token": "eyJhbGciOiJIUzI1NiIs...",
|
|||
|
|
"expires_at": 1234567890.123,
|
|||
|
|
"expires_in": 900
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
缓存策略:
|
|||
|
|
- 令牌在过期前 `AUTH_MIN_TTL_SEC` 秒内视为无效
|
|||
|
|
- 默认最小 TTL 为 60 秒
|
|||
|
|
- 缓存文件自动创建和删除
|
|||
|
|
|
|||
|
|
## 错误处理
|
|||
|
|
|
|||
|
|
### 常见错误
|
|||
|
|
|
|||
|
|
| 错误 | 原因 | 解决方案 |
|
|||
|
|
|------|------|---------|
|
|||
|
|
| `CLIENT_KEY is required` | 未设置 CLIENT_KEY | 在 .env 文件或环境变量中设置 |
|
|||
|
|
| `Auth session request failed` | 认证请求失败 | 检查 CLIENT_KEY 是否有效 |
|
|||
|
|
| `Missing accessToken` | 认证响应缺少令牌 | 检查认证服务是否正常 |
|
|||
|
|
|
|||
|
|
### 自动重试
|
|||
|
|
|
|||
|
|
以下情况会自动刷新令牌并重试一次:
|
|||
|
|
- HTTP 401 Unauthorized
|
|||
|
|
- HTTP 403 Forbidden
|
|||
|
|
- 响应体包含 "expired"、"unauthorized" 等标记
|
|||
|
|
|
|||
|
|
## 测试
|
|||
|
|
|
|||
|
|
运行测试脚本:
|
|||
|
|
|
|||
|
|
```bash
|
|||
|
|
cd /Users/xiaolongxia/Documents/ai-build-app/skills/excel-toolkit
|
|||
|
|
uv run python scripts/test_auth.py
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
## 与 TypeScript 版本的差异
|
|||
|
|
|
|||
|
|
| 特性 | TypeScript | Python |
|
|||
|
|
|------|-----------|--------|
|
|||
|
|
| HTTP 客户端 | 原生 fetch | requests |
|
|||
|
|
| 缓存文件 | Bun/Node fs | pathlib |
|
|||
|
|
| 环境变量 | process.env | os.getenv |
|
|||
|
|
| 类型系统 | TypeScript | dataclass |
|
|||
|
|
|
|||
|
|
功能完全对等,可以互换使用。
|
|||
|
|
|
|||
|
|
## 获取 CLIENT_KEY
|
|||
|
|
|
|||
|
|
CLIENT_KEY 存储在 `~/clawd/skills/_shared` 目录中。
|
|||
|
|
|
|||
|
|
查看相关文档:
|
|||
|
|
- `~/clawd/skills/_shared/AUTH_RUNTIME_IMPLEMENTATION.md`
|
|||
|
|
- `~/clawd/skills/_shared/auth-runtime/README.md`
|
|||
|
|
|
|||
|
|
## 许可证
|
|||
|
|
|
|||
|
|
与 OpenClaw 项目保持一致。
|