Initial commit: SMS Receiver Web Service
Features: - Receive SMS from TranspondSms Android APP - HMAC-SHA256 signature verification (optional) - SQLite database storage - Web UI with login authentication - Multiple API tokens support - Timezone conversion (Asia/Shanghai) - Search, filter, and statistics - Auto refresh and session management Tech Stack: - Flask 3.0 - SQLite database - HTML5/CSS3 responsive design
This commit is contained in:
961
DEVELOPMENT.md
Normal file
961
DEVELOPMENT.md
Normal file
@@ -0,0 +1,961 @@
|
||||
# 短信转发接收端 - 开发文档
|
||||
|
||||
## 目录
|
||||
|
||||
- [项目概述](#项目概述)
|
||||
- [实现逻辑](#实现逻辑)
|
||||
- [使用指南](#使用指南)
|
||||
- [部署指南](#部署指南)
|
||||
- [API 文档](#api-文档)
|
||||
- [配置说明](#配置说明)
|
||||
- [常见问题](#常见问题)
|
||||
- [开发规范](#开发规范)
|
||||
|
||||
---
|
||||
|
||||
## 项目概述
|
||||
|
||||
### 技术架构
|
||||
|
||||
```
|
||||
┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐
|
||||
│ Android APP │ │ Flask Web │ │ SQLite DB │
|
||||
│ TranspondSms │────────▶│ Server │────────▶│ sms_receiver │
|
||||
│ │ POST │ │ Store │ .db │
|
||||
└─────────────────┘ └─────────────────┘ └─────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────┐
|
||||
│ Web UI │
|
||||
│ (登录认证) │
|
||||
└─────────────────┘
|
||||
```
|
||||
|
||||
### 核心功能
|
||||
|
||||
1. **短信接收**:接收 TranspondSms Android APP 转发的短信
|
||||
2. **签名验证**:HMAC-SHA256 签名验证,防止伪造请求
|
||||
3. **数据存储**:SQLite 数据库存储短信和日志
|
||||
4. **Web 管理**:登录验证 + 短信列表、详情、日志、统计
|
||||
5. **时区转换**:UTC 存储时区转换显示
|
||||
6. **Token 配置**:支持多设备、多 Token 配置
|
||||
|
||||
---
|
||||
|
||||
## 实现逻辑
|
||||
|
||||
### 1. 整体数据流
|
||||
|
||||
```
|
||||
Android APP 接收短信
|
||||
│
|
||||
├─ 解析短信内容(支持多PDU)
|
||||
├─ 提取发送方、内容、时间戳
|
||||
├─ 可选:生成签名(HMAC-SHA256)
|
||||
│
|
||||
▼
|
||||
POST 请求发送到 /api/receive
|
||||
│
|
||||
├─ 解析 multipart/form-data
|
||||
├─ 验证必填参数(from, content)
|
||||
├─ 可选:验证签名
|
||||
│ ├─ 检查时间戳是否过期
|
||||
│ ├─ 生成期望的签名
|
||||
│ └─ 比较签名是否匹配
|
||||
│
|
||||
├─ 保存到数据库
|
||||
│ ├─ 存储为 UTC 时间
|
||||
│ ├─ 关联 Token 和 Secret
|
||||
│ └─ 记录接收日志
|
||||
│
|
||||
▼
|
||||
返回成功响应
|
||||
```
|
||||
|
||||
### 2. 签名验证逻辑
|
||||
|
||||
TranspondSms 的签名规则:
|
||||
|
||||
```python
|
||||
# 1. 拼接待签名字符串
|
||||
string_to_sign = timestamp + "\n" + secret
|
||||
|
||||
# 2. HMAC-SHA256 计算
|
||||
hmac_code = hmac.new(
|
||||
secret.encode('utf-8'),
|
||||
string_to_sign.encode('utf-8'),
|
||||
digestmod=hashlib.sha256
|
||||
).digest()
|
||||
|
||||
# 3. Base64 编码
|
||||
sign_bytes = base64.b64encode(hmac_code)
|
||||
|
||||
# 4. URL 编码
|
||||
sign = urllib.parse.quote(sign_bytes.decode())
|
||||
```
|
||||
|
||||
**防重放攻击**:
|
||||
- 检查时间戳是否在允许范围内(默认1小时)
|
||||
- 超出范围的请求拒绝
|
||||
|
||||
### 3. 时区转换逻辑
|
||||
|
||||
```
|
||||
数据库存储(UTC)
|
||||
│
|
||||
├─ created_at: 2024-02-06 14:30:00 (UTC)
|
||||
└─ timestamp: 1707223800000 (毫秒时间戳)
|
||||
│
|
||||
▼
|
||||
读取时转换
|
||||
│
|
||||
├─ UTC 时间 + 时区偏移(8小时)
|
||||
└─ datetime.fromtimestamp(timestamp / 1000)
|
||||
│
|
||||
▼
|
||||
显示(本地时间)
|
||||
│
|
||||
└─ created_at: 2024-02-06 22:30:00 (Asia/Shanghai)
|
||||
```
|
||||
|
||||
### 4. 登录验证流程
|
||||
|
||||
```
|
||||
用户访问页面
|
||||
│
|
||||
▼
|
||||
检查 session['logged_in']
|
||||
│
|
||||
├─ 已登录 ──▶ 更新 last_activity ──▶ 允许访问
|
||||
│
|
||||
└─ 未登录 ──▶ 跳转到 /login
|
||||
│
|
||||
▼
|
||||
提交表单
|
||||
│
|
||||
├─ 验证用户名和密码
|
||||
│
|
||||
├─ 成功:
|
||||
│ ├─ session['logged_in'] = True
|
||||
│ ├─ session['username'] = username
|
||||
│ ├─ session['login_time'] = now
|
||||
│ └─ 跳转到原页面或首页
|
||||
│
|
||||
└─ 失败:显示错误消息
|
||||
```
|
||||
|
||||
**会话超时检查**:
|
||||
```python
|
||||
last_activity = session.get('last_activity')
|
||||
if now - last_activity > SESSION_LIFETIME:
|
||||
# 清空会话,重定向到登录页
|
||||
session.clear()
|
||||
return redirect('/login')
|
||||
```
|
||||
|
||||
### 5. Token 匹配逻辑
|
||||
|
||||
```python
|
||||
# 接收请求时
|
||||
token = request.form.get('token') # 从参数获取
|
||||
|
||||
# 在配置中查找对应的 secret
|
||||
for token_config in API_TOKENS:
|
||||
if token_config['token'] == token and token_config['enabled']:
|
||||
secret = token_config['secret']
|
||||
break
|
||||
|
||||
# 使用找到的 secret 进行签名验证
|
||||
if secret and SIGN_VERIFY:
|
||||
verify_sign(secret, sign, timestamp)
|
||||
```
|
||||
|
||||
### 6. 数据库设计
|
||||
|
||||
#### sms_messages 表
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| id | INTEGER | 主键,自增 |
|
||||
| from_number | TEXT | 发送方手机号 |
|
||||
| content | TEXT | 短信内容 |
|
||||
| timestamp | INTEGER | 原始时间戳(毫秒) |
|
||||
| device_info | TEXT | 设备信息(可选) |
|
||||
| sim_info | TEXT | SIM 卡信息(可选) |
|
||||
| sign_verified | INTEGER | 是否通过签名验证(0/1) |
|
||||
| ip_address | TEXT | 来源 IP 地址 |
|
||||
| created_at | TIMESTAMP | 创建时间(UTC) |
|
||||
|
||||
#### receive_logs 表
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| id | INTEGER | 主键,自增 |
|
||||
| from_number | TEXT | 发送方手机号 |
|
||||
| content | TEXT | 短信内容 |
|
||||
| timestamp | INTEGER | 时间戳 |
|
||||
| sign | TEXT | 签名 |
|
||||
| sign_valid | INTEGER | 签名是否有效(0/1/null) |
|
||||
| ip_address | TEXT | IP 地址 |
|
||||
| status | TEXT | 处理状态(success/error) |
|
||||
| error_message | TEXT | 错误消息 |
|
||||
| created_at | TIMESTAMP | 创建时间(UTC)**
|
||||
|
||||
### 分层架构
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Flask Application Layer │
|
||||
│ (app.py - 路由、业务逻辑、会话管理) │
|
||||
└─────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Database Layer │
|
||||
│ (database.py - 数据库操作、时区转换) │
|
||||
└─────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────┐
|
||||
│ SQLite Database │
|
||||
│ (sms_receiver.db - 数据持久化) │
|
||||
└─────────────────────────────────────────┘
|
||||
│
|
||||
▼
|
||||
┌─────────────────────────────────────────┐
|
||||
│ Template Layer │
|
||||
│ (templates/ - HTML、CSS、JS) │
|
||||
└─────────────────────────────────────────┘
|
||||
```
|
||||
|
||||
### 核心模块职责
|
||||
|
||||
| 模块 | 职责 |
|
||||
|------|------|
|
||||
| `app.py` | Flask 主应用,路由注册,业务逻辑 |
|
||||
| `config.py` | 配置加载,从 config.json 读取配置 |
|
||||
| `database.py` | 数据库模型,CRUD 操作,时区转换 |
|
||||
| `sign_verify.py` | 签名生成和验证 |
|
||||
| `templates/` | HTML 模板,前端展示 |
|
||||
|
||||
---
|
||||
|
||||
## 使用指南
|
||||
|
||||
### 前置要求
|
||||
|
||||
- Python 3.7+
|
||||
- Flask 3.0+
|
||||
- SQLite3
|
||||
|
||||
### 安装依赖
|
||||
|
||||
```bash
|
||||
pip install -r requirements.txt
|
||||
```
|
||||
|
||||
### 配置文件
|
||||
|
||||
创建 `config.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"server": {
|
||||
"host": "0.0.0.0",
|
||||
"port": 9518,
|
||||
"debug": false
|
||||
},
|
||||
"security": {
|
||||
"enabled": true,
|
||||
"username": "admin",
|
||||
"password": "YourStrongPassword123",
|
||||
"session_lifetime": 3600,
|
||||
"secret_key": "RandomSecretKeyHere",
|
||||
"sign_verify": true,
|
||||
"sign_max_age": 3600000
|
||||
},
|
||||
"sms": {
|
||||
"max_messages": 10000,
|
||||
"auto_cleanup": true,
|
||||
"cleanup_days": 30
|
||||
},
|
||||
"database": {
|
||||
"path": "sms_receiver.db"
|
||||
},
|
||||
"timezone": "Asia/Shanghai",
|
||||
"api_tokens": [
|
||||
{
|
||||
"name": "我的手机",
|
||||
"token": "my_phone_token",
|
||||
"secret": "my_phone_secret",
|
||||
"enabled": true
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 启动服务
|
||||
|
||||
```bash
|
||||
python3 app.py
|
||||
```
|
||||
|
||||
服务启动后访问:http://你的IP:9518
|
||||
|
||||
### 配置 TranspondSms APP
|
||||
|
||||
1. 下载并安装 TranspondSms APP
|
||||
2. 打开 APP,进入"发送方"页面
|
||||
3. 添加"网页通知"
|
||||
4. 填写配置:
|
||||
|
||||
```
|
||||
Token (URL): http://你的服务器IP:9518/api/receive?token=my_phone_token
|
||||
Secret: my_phone_secret
|
||||
```
|
||||
|
||||
5. 点击"测试"按钮,验证是否成功
|
||||
6. 配置转发规则(如"转发全部")
|
||||
|
||||
### 使用 Web 界面
|
||||
|
||||
#### 登录
|
||||
|
||||
- 访问 http://你的IP:9518
|
||||
- 输入用户名和密码
|
||||
- 登录成功后进入短信列表
|
||||
|
||||
#### 查看短信
|
||||
|
||||
- **短信列表**:主页显示所有收到短信
|
||||
- **搜索**:支持按号码或内容搜索
|
||||
- **筛选**:按发送方号码快捷筛选
|
||||
- **详情**:点击短信查看完整内容和元数据
|
||||
|
||||
#### 查看日志
|
||||
|
||||
- 访问"接收日志"页面
|
||||
- 查看每次请求的处理结果
|
||||
- 包括签名验证状态、IP 地址、错误信息
|
||||
|
||||
#### 统计信息
|
||||
|
||||
- 访问"统计信息"页面
|
||||
- 查看短信总数、今日、本周
|
||||
- 签名验证比例
|
||||
- 发送方号码排行榜
|
||||
- 清理旧数据
|
||||
|
||||
---
|
||||
|
||||
## 部署指南
|
||||
|
||||
### 开发环境部署
|
||||
|
||||
```bash
|
||||
# 克隆项目
|
||||
git clone <your-repo-url>
|
||||
cd smsweb
|
||||
|
||||
# 创建虚拟环境(推荐)
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
|
||||
# 安装依赖
|
||||
pip install -r requirements.txt
|
||||
|
||||
# 配置 config.json
|
||||
cp config.example.json config.json
|
||||
vim config.json
|
||||
|
||||
# 启动服务
|
||||
python3 app.py
|
||||
```
|
||||
|
||||
### 生产环境部署(推荐方案)
|
||||
|
||||
#### 1. 使用 Gunicorn + Nginx
|
||||
|
||||
**安装 Gunicorn**:
|
||||
|
||||
```bash
|
||||
pip install gunicorn
|
||||
```
|
||||
|
||||
**创建 systemd 服务**:
|
||||
|
||||
```bash
|
||||
sudo vim /etc/systemd/system/sms-receiver.service
|
||||
```
|
||||
|
||||
内容:
|
||||
|
||||
```ini
|
||||
[Unit]
|
||||
Description=SMS Receiver Service
|
||||
After=network.target
|
||||
|
||||
[Service]
|
||||
Type=notify
|
||||
User=www-data
|
||||
WorkingDirectory=/var/www/sms-receiver
|
||||
Environment="PATH=/var/www/sms-receiver/venv/bin"
|
||||
ExecStart=/var/www/sms-receiver/venv/bin/gunicorn \
|
||||
-w 4 -b 127.0.0.1:9518 \
|
||||
--timeout 120 \
|
||||
--access-logfile /var/log/sms-receiver/access.log \
|
||||
--error-logfile /var/log/sms-receiver/error.log \
|
||||
app:app
|
||||
Restart=always
|
||||
RestartSec=10
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
```
|
||||
|
||||
**启动服务**:
|
||||
|
||||
```bash
|
||||
sudo systemctl daemon-reload
|
||||
sudo systemctl enable sms-receiver
|
||||
sudo systemctl start sms-receiver
|
||||
sudo systemctl status sms-receiver
|
||||
```
|
||||
|
||||
**配置 Nginx 反向代理**:
|
||||
|
||||
```bash
|
||||
sudo vim /etc/nginx/sites-available/sms-receiver
|
||||
```
|
||||
|
||||
内容:
|
||||
|
||||
```nginx
|
||||
upstream sms_receiver {
|
||||
server 127.0.0.1:9518;
|
||||
}
|
||||
|
||||
server {
|
||||
listen 80;
|
||||
server_name sms.example.com;
|
||||
|
||||
access_log /var/log/nginx/sms-receiver-access.log;
|
||||
error_log /var/log/nginx/sms-receiver-error.log;
|
||||
|
||||
location / {
|
||||
proxy_pass http://sms_receiver;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
proxy_set_header X-Forwarded-Proto $scheme;
|
||||
proxy_redirect off;
|
||||
proxy_buffering off;
|
||||
}
|
||||
|
||||
# 接收 API 不需要登录,但对客户端透明
|
||||
location /api/receive {
|
||||
proxy_pass http://sms_receiver/api/receive;
|
||||
proxy_set_header Host $host;
|
||||
proxy_set_header X-Real-IP $remote_addr;
|
||||
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**启用站点**:
|
||||
|
||||
```bash
|
||||
sudo ln -s /etc/nginx/sites-available/sms-receiver /etc/nginx/sites-enabled/
|
||||
sudo nginx -t
|
||||
sudo systemctl reload nginx
|
||||
```
|
||||
|
||||
#### 2. 配置 HTTPS(Let's Encrypt)
|
||||
|
||||
```bash
|
||||
sudo certbot --nginx -d sms.example.com
|
||||
```
|
||||
|
||||
#### 3. 防火墙配置
|
||||
|
||||
```bash
|
||||
sudo ufw allow 80/tcp
|
||||
sudo ufw allow 443/tcp
|
||||
sudo ufw enable
|
||||
```
|
||||
|
||||
#### 4. 日志轮转
|
||||
|
||||
```bash
|
||||
sudo vim /etc/logrotate.d/sms-receiver
|
||||
```
|
||||
|
||||
内容:
|
||||
|
||||
```
|
||||
/var/log/sms-receiver/*.log {
|
||||
daily
|
||||
rotate 14
|
||||
compress
|
||||
missingok
|
||||
notifempty
|
||||
create 0640 www-data www-data
|
||||
sharedscripts
|
||||
postrotate
|
||||
systemctl reload sms-receiver >/dev/null 2>&1 || true
|
||||
endscript
|
||||
}
|
||||
```
|
||||
|
||||
### Docker 部署
|
||||
|
||||
**创建 Dockerfile**:
|
||||
|
||||
```dockerfile
|
||||
FROM python:3.11-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
RUN apt-get update && apt-get install -y \
|
||||
gcc \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
COPY requirements.txt .
|
||||
RUN pip install --no-cache-dir -r requirements.txt
|
||||
|
||||
COPY . .
|
||||
|
||||
EXPOSE 9518
|
||||
|
||||
CMD ["gunicorn", "-w", "4", "-b", "0.0.0.0:9518", "app:app"]
|
||||
```
|
||||
|
||||
**创建 docker-compose.yml**:
|
||||
|
||||
```yaml
|
||||
version: '3.8'
|
||||
|
||||
services:
|
||||
sms-receiver:
|
||||
build: .
|
||||
ports:
|
||||
- "9518:9518"
|
||||
volumes:
|
||||
- ./sms_receiver.db:/app/sms_receiver.db
|
||||
- ./config.json:/app/config.json
|
||||
- ./logs:/app/logs
|
||||
environment:
|
||||
- FLASK_ENV=production
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
**启动**:
|
||||
|
||||
```bash
|
||||
docker-compose up -d
|
||||
```
|
||||
|
||||
### 安全加固
|
||||
|
||||
1. **修改默认密码**:首次部署后立即修改登录密码
|
||||
2. **使用强密码**:至少16位,包含大小写字母、数字、特殊字符
|
||||
3. **启用 HTTPS**:使用 Let's Encrypt 免费证书
|
||||
4. **限制访问**:配置防火墙,只开放必要端口
|
||||
5. **启用签名验证**:设置 Token 的 secret
|
||||
6. **定期更新**:定期更新 Python 和 Flask 版本
|
||||
|
||||
### 监控和维护
|
||||
|
||||
**查看日志**:
|
||||
|
||||
```bash
|
||||
# 应用日志
|
||||
tail -f /var/log/sms-receiver/error.log
|
||||
|
||||
# Nginx 日志
|
||||
tail -f /var/log/nginx/sms-receiver-error.log
|
||||
```
|
||||
|
||||
**备份数据库**:
|
||||
|
||||
```bash
|
||||
#!/bin/bash
|
||||
BACKUP_DIR="/backup/sms-receiver"
|
||||
DATE=$(date +%Y%m%d_%H%M%S)
|
||||
mkdir -p $BACKUP_DIR
|
||||
|
||||
# 备份数据库
|
||||
cp /var/www/sms-receiver/sms_receiver.db $BACKUP_DIR/sms_receiver_$DATE.db
|
||||
|
||||
# 备份配置
|
||||
cp /var/www/sms-receiver/config.json $BACKUP_DIR/config_$DATE.json
|
||||
|
||||
# 删除30天前的备份
|
||||
find $BACKUP_DIR -name "*.db" -mtime +30 -delete
|
||||
find $BACKUP_DIR -name "*.json" -mtime +30 -delete
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## API 文档
|
||||
|
||||
### POST /api/receive
|
||||
|
||||
接收短信接口。
|
||||
|
||||
**请求方式**:POST multipart/form-data
|
||||
|
||||
**URL 参数**:
|
||||
- `token` (可选): API Token,用于匹配对应的 secret
|
||||
|
||||
**表单参数**:
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|------|------|------|------|
|
||||
| from | string | 是 | 发送方手机号 |
|
||||
| content | string | 是 | 短信内容 |
|
||||
| timestamp | string | 否 | 时间戳(毫秒),用于签名验证 |
|
||||
| sign | string | 否 | 签名(HMAC-SHA256 + Base64 + URL Encode) |
|
||||
| device | string | 否 | 设备信息 |
|
||||
| sim | string | 否 | SIM 卡信息 |
|
||||
|
||||
**请求示例**:
|
||||
|
||||
```bash
|
||||
curl -X POST http://your-server:9518/api/receive?token=my_token \
|
||||
-F "from=10086" \
|
||||
-F "content=验证码: 123456" \
|
||||
-F "timestamp=1707223800000" \
|
||||
-F "sign=xxx"
|
||||
```
|
||||
|
||||
**响应示例**:
|
||||
|
||||
成功:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"message_id": 123,
|
||||
"message": "短信已接收"
|
||||
}
|
||||
```
|
||||
|
||||
失败:
|
||||
```json
|
||||
{
|
||||
"error": "缺少必填参数"
|
||||
}
|
||||
```
|
||||
|
||||
**HTTP 状态码**:
|
||||
- 200: 成功
|
||||
- 400: 参数错误
|
||||
- 403: 签名验证失败
|
||||
- 500: 服务器错误
|
||||
|
||||
### GET /api/messages
|
||||
|
||||
获取短信列表(需要登录)。
|
||||
|
||||
**URL 参数**:
|
||||
| 参数 | 类型 | 必填 | 说明 |
|
||||
|------|------|------|------|
|
||||
| page | int | 否 | 页码,默认1 |
|
||||
| limit | int | 否 | 每页数量,默认20 |
|
||||
| from | string | 否 | 按发送方号码筛选 |
|
||||
| search | string | 否 | 搜索内容或号码 |
|
||||
|
||||
**响应示例**:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": [
|
||||
{
|
||||
"id": 1,
|
||||
"from_number": "10086",
|
||||
"content": "验证码: 123456",
|
||||
"timestamp": 1707223800000,
|
||||
"local_timestamp": "2024-02-06 22:30:00",
|
||||
"created_at": "2024-02-06 14:30:00",
|
||||
"sign_verified": true
|
||||
}
|
||||
],
|
||||
"total": 1,
|
||||
"page": 1,
|
||||
"limit": 20
|
||||
}
|
||||
```
|
||||
|
||||
### GET /api/statistics
|
||||
|
||||
获取统计信息(需要登录)。
|
||||
|
||||
**响应示例**:
|
||||
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"data": {
|
||||
"total": 100,
|
||||
"today": 10,
|
||||
"week": 50,
|
||||
"verified": 80,
|
||||
"unverified": 20
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 配置说明
|
||||
|
||||
### 完整配置示例
|
||||
|
||||
```json
|
||||
{
|
||||
"app": {
|
||||
"name": "短信转发接收端",
|
||||
"version": "1.0.0"
|
||||
},
|
||||
"server": {
|
||||
"host": "0.0.0.0",
|
||||
"port": 9518,
|
||||
"debug": false
|
||||
},
|
||||
"security": {
|
||||
"enabled": true,
|
||||
"username": "admin",
|
||||
"password": "YourStrongPassword123",
|
||||
"session_lifetime": 3600,
|
||||
"secret_key": "RandomSecretKeyChangeMe",
|
||||
"sign_verify": true,
|
||||
"sign_max_age": 3600000
|
||||
},
|
||||
"sms": {
|
||||
"max_messages": 10000,
|
||||
"auto_cleanup": true,
|
||||
"cleanup_days": 30
|
||||
},
|
||||
"database": {
|
||||
"path": "sms_receiver.db"
|
||||
},
|
||||
"timezone": "Asia/Shanghai",
|
||||
"api_tokens": [
|
||||
{
|
||||
"name": "主手机",
|
||||
"token": "main_phone_token",
|
||||
"secret": "main_phone_secret_key",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "备用机",
|
||||
"token": "backup_phone_token",
|
||||
"secret": "backup_phone_secret_key",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "测试设备",
|
||||
"token": "test_token",
|
||||
"secret": "",
|
||||
"enabled": false
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### 配置项详解
|
||||
|
||||
#### server - 服务器配置
|
||||
|
||||
| 字段 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| host | string | 0.0.0.0 | 监听地址 |
|
||||
| port | int | 9518 | 监听端口 |
|
||||
| debug | bool | false | 调试模式 |
|
||||
|
||||
#### security - 安全配置
|
||||
|
||||
| 字段 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| enabled | bool | true | 是否启用登录验证 |
|
||||
| username | string | admin | 登录用户名 |
|
||||
| password | string | admin123 | 登录密码 |
|
||||
| session_lifetime | int | 3600 | 会话有效期(秒) |
|
||||
| secret_key | string | - | Flask 会话密钥 |
|
||||
| sign_verify | bool | true | 是否验证签名 |
|
||||
| sign_max_age | int | 3600000 | 签名最大有效时间(毫秒) |
|
||||
|
||||
#### sms - 短信配置
|
||||
|
||||
| 字段 | 类型 | 默认值 | 说明 |
|
||||
|------|------|--------|------|
|
||||
| max_messages | int | 10000 | 最多保留短信数 |
|
||||
| auto_cleanup | bool | true | 是否自动清理老数据 |
|
||||
| cleanup_days | int | 30 | 清理多少天前的数据 |
|
||||
|
||||
#### api_tokens - API Token 配置
|
||||
|
||||
| 字段 | 类型 | 说明 |
|
||||
|------|------|------|
|
||||
| name | string | 配置名称(可选) |
|
||||
| token | string | Token 值,用于匹配 secret |
|
||||
| secret | string | 密钥,用于签名验证(可选) |
|
||||
| enabled | bool | 是否启用此 Token |
|
||||
|
||||
---
|
||||
|
||||
## 常见问题
|
||||
|
||||
### Q1: 如何禁用登录验证?
|
||||
|
||||
在 `config.json` 中设置:
|
||||
|
||||
```json
|
||||
{
|
||||
"security": {
|
||||
"enabled": false
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Q2:签名验证失败怎么办?
|
||||
|
||||
检查以下几点:
|
||||
|
||||
1. **时间戳是否正确**:确保客户端时间准确,误差不超过1小时
|
||||
2. **Secret 是否匹配**:确保客户端和服务器端的 secret 完全一致
|
||||
3. **签名生成算法**:使用正确的算法(HMAC-SHA256)
|
||||
|
||||
**调试签名**:
|
||||
|
||||
```python
|
||||
# 生成签名
|
||||
import time, hmac, hashlib, base64, urllib.parse
|
||||
|
||||
timestamp = str(int(time.time() * 1000))
|
||||
secret = "your_secret"
|
||||
string_to_sign = f"{timestamp}\n{secret}"
|
||||
sign = urllib.parse.quote(base64.b64encode(
|
||||
hmac.new(secret.encode(), string_to_sign.encode(), hashlib.sha256).digest()
|
||||
).decode())
|
||||
|
||||
print(f"Timestamp: {timestamp}")
|
||||
print(f"Sign: {sign}")
|
||||
```
|
||||
|
||||
### Q3: 如何配置多个设备?
|
||||
|
||||
在 `api_tokens` 中添加多个配置:
|
||||
|
||||
```json
|
||||
{
|
||||
"api_tokens": [
|
||||
{
|
||||
"name": "设备A",
|
||||
"token": "device_a",
|
||||
"secret": "secret_a",
|
||||
"enabled": true
|
||||
},
|
||||
{
|
||||
"name": "设备B",
|
||||
"token": "device_b",
|
||||
"secret": "secret_b",
|
||||
"enabled": true
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
在 APP 中配置不同的设备使用不同的 Token。
|
||||
|
||||
### Q4: 会话总是过期?
|
||||
|
||||
调整 `session_lifetime`:
|
||||
|
||||
```json
|
||||
{
|
||||
"security": {
|
||||
"session_lifetime": 86400 // 24小时
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Q5: 如何备份数据?
|
||||
|
||||
直接复制数据库文件:
|
||||
|
||||
```bash
|
||||
cp sms_receiver.db sms_receiver.db.backup
|
||||
```
|
||||
|
||||
或者使用 SQLite 导出:
|
||||
|
||||
```bash
|
||||
sqlite3 sms_receiver.db ".dump" > backup.sql
|
||||
```
|
||||
|
||||
### Q6: 如何清理所有数据?
|
||||
|
||||
删除数据库文件,重启服务会自动重建:
|
||||
|
||||
```bash
|
||||
rm sms_receiver.db
|
||||
python3 app.py
|
||||
```
|
||||
|
||||
### Q7: 时间显示不正确?
|
||||
|
||||
检查时区配置:
|
||||
|
||||
```json
|
||||
{
|
||||
"timezone": "Asia/Shanghai"
|
||||
}
|
||||
```
|
||||
|
||||
可用时区列表:https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
||||
|
||||
---
|
||||
|
||||
## 开发规范
|
||||
|
||||
### 代码风格
|
||||
|
||||
- 遵循 PEP 8 Python 代码规范
|
||||
- 使用有意义的变量和函数名
|
||||
- 添加必要的类型注解
|
||||
|
||||
### Git 提交规范
|
||||
|
||||
```
|
||||
feat: 添加新功能
|
||||
fix: 修复 bug
|
||||
docs: 更新文档
|
||||
style: 代码格式化
|
||||
refactor: 重构
|
||||
test: 添加测试
|
||||
chore: 构建/工具链
|
||||
```
|
||||
|
||||
### 测试建议
|
||||
|
||||
```python
|
||||
# 测试签名生成
|
||||
python3 sign_verify.py
|
||||
|
||||
# 测试 API
|
||||
curl -X POST http://localhost:9518/api/receive \
|
||||
-F "from=10086" \
|
||||
-F "content=test"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 许可证
|
||||
|
||||
MIT License
|
||||
|
||||
## 联系方式
|
||||
|
||||
- 项目地址:https://gitea.king.nyc.mn/openclaw/smsweb
|
||||
- 问题反馈:提交 Issue
|
||||
Reference in New Issue
Block a user