# Casdoor 对接短信中转站

本文档按 Casdoor 后台 **Custom HTTP SMS** 配置界面逐项填写（与当前截图一致）。

**中转站地址**：`https://sms.finally.chat/send.php`

**服务端 `config.php`（勿写入 Casdoor）**：

| 配置项 | 值 |
|--------|-----|
| UniSMS 签名 | `芒市云脉网络` |
| UniSMS 模板 ID | `dbed3982` |
| 模板变量 `ttl` | `10`（分钟） |
| 中转站 API Key | 未启用 |

---

## 一、Provider 表单填写（与界面一致）

路径：**Providers → Add / Edit → Category: `SMS` → Type: `Custom HTTP SMS`**

### 1. 接口与请求

| 界面字段 | 填写值 |
|----------|--------|
| **地域节点 (外网) / Endpoint** | `https://sms.finally.chat/send.php` |
| **方法 / Method** | `POST` |
| **内容类型 / Content-Type** | `application/json` |
| **HTTP 标头 / HTTP Headers** | 留空（暂无数据） |
| **启用代理 / Enable Proxy** | **关闭** |
| **提供商 URL / Provider URL** | 留空 |

### 2. HTTP Body 映射

| 界面字段 | 填写值 |
|----------|--------|
| **手机号 / Phone Number** | **留空** |
| **内容 / Content** | **留空** |

留空时使用 Casdoor 默认字段名 `phoneNumber` 发手机号。

### 3. 参数

| 界面字段 | 填写值 |
|----------|--------|
| **参数 / Parameters** | `code` |

表示 Casdoor 将**拼好的整段短信正文**写入 JSON 的 `code` 字段（不是只发 4 位数字）。中转站已支持该写法。

### 4. 模板（同页或「Template」相关项，需单独填写）

| 字段 | 填写值 |
|------|--------|
| **Template code / 模板** | `您的验证码是%s，10分钟内有效。` |

`%s` 由 Casdoor 替换为验证码；须包含 `%s`，以便中转站提取验证码并填入 UniSMS 模板 `dbed3982`。

### 5. 名称（自定）

| 字段 | 建议值 |
|------|--------|
| **Name** | `unisms-relay` |
| **Display name** | `UniSMS 短信` |

保存 Provider。

---

## 二、启用 Provider

1. **Organizations** → 你的组织 → **Providers** → 勾选该 SMS Provider。  
2. **Applications** → 你的应用 → **Providers** → 同样勾选。  
3. 应用登录方式中启用 **Phone**（手机验证码）。

---

## 三、Casdoor 实际请求示例

与上图配置对应，Casdoor 会 POST：

```http
POST https://sms.finally.chat/send.php HTTP/1.1
Content-Type: application/json

{
  "phoneNumber": "1860571xxxx",
  "code": "您的验证码是9153，10分钟内有效。"
}
```

说明：

- `phoneNumber`：Body 映射留空时的默认字段。  
- `code`：对应界面 **参数** 填写的 `code`，值为模板替换 `%s` 后的完整正文。  

中转站从 `code` 正文中提取验证码（如 `9153`），再调用 UniSMS：签名 `芒市云脉网络`，模板 `dbed3982`，`templateData`: `{"code":"9153","ttl":"10"}`。

---

## 四、成功标准

| 结果 | HTTP 状态 |
|------|-----------|
| 发送成功 | `200` |
| 参数/验证码错误 | `400` |
| UniSMS 或网络错误 | `502` 等 |

成功响应示例：

```json
{
  "ok": true,
  "message": "Success",
  "unisms": { }
}
```

---

## 五、命令行自测（模拟 Casdoor）

```bash
curl -X POST 'https://sms.finally.chat/send.php' \
  -H 'Content-Type: application/json' \
  -d '{
    "phoneNumber": "你的手机号",
    "code": "您的验证码是123456，10分钟内有效。"
  }'
```

---

## 六、可选：HTTP 标头鉴权

若在 `config.php` 设置 `relay.api_key`，在 **HTTP 标头** 增加一行：

| 密钥 | 值 |
|------|-----|
| `X-Relay-Key` | 与 `config.php` 中 `api_key` 相同 |

---

## 七、常见问题

| 现象 | 处理 |
|------|------|
| 发送失败 / 收不到短信 | 确认 **参数** 为 `code`，且模板含 `%s` |
| `SmsSignatureNotExists` | UniSMS 控制台签名须为 `芒市云脉网络` |
| `SmsTemplateNotExists` | 确认模板 ID `dbed3982` 已通过 |
| `InsufficientFunds` | UniSMS 账户充值 |
| Casdoor 仍失败 | 组织与应用是否已勾选该 Provider |

---

## 八、架构

```
用户 → Casdoor（模板 + %s → 写入 code 字段）
         ↓ POST /send.php
      短信中转站
         ↓ UniSMS（签名 + 模板 dbed3982）
      用户手机
```
