neocrates 0.1.45

A comprehensive Rust library for various utilities and helpers
Documentation
# SMS Service Module

这个模块提供短信验证码发送与校验的能力,支持多短信服务商(当前已内置 **Aliyun** / **Tencent**),并将验证码写入 Redis 以便后续校验。

> 示例代码见:`examples/sms_example.rs`

---

## 功能特性

- 生成 6 位数字验证码
- 通过短信服务商发送验证码
- 发送成功后写入 Redis(避免“没收到短信却能登录”)
- 校验验证码(可选校验成功后删除,实现一次性验证码)
- `debug` 模式:不发短信,只写 Redis,便于本地联调

---

## 依赖与 Features

示例依赖 Redis,并会调用 HTTP(短信服务商 API)。

运行示例推荐开启 `full`:

```bash
cargo run --example sms_example --features full
```

如果你只想按需开启,请确保至少包含:
- `sms`
- `redis`
- `web`(因为 provider 内部依赖 `reqwest` / `urlencoding` 等)

> 由于项目的 feature 组合可能会调整,最稳妥是使用 `--features full` 来运行 examples。

---

## 环境准备

### 1) 启动 Redis

```bash
# macOS/Linux
redis-server

# Docker
docker run -d -p 6379:6379 redis:latest
```

可选:指定 Redis 连接串:

```bash
export REDIS_URL="redis://127.0.0.1:6379"
```

---

## 运行示例:sms_example

### 快速开始(推荐:debug 模式)

不想发真实短信时,可以开启 debug 模式:验证码只写 Redis,不会请求短信服务商。

```bash
export SMS_DEBUG=true
export SMS_PROVIDER=aliyun
export MOBILE=13800138000

cargo run --example sms_example --features full
```

---

## Provider 选择

示例通过环境变量 `SMS_PROVIDER` 选择短信服务商:

- `SMS_PROVIDER=aliyun`(默认)
- `SMS_PROVIDER=tencent`

```bash
export SMS_PROVIDER=aliyun
# 
export SMS_PROVIDER=tencent
```

---

## Aliyun 配置(SMS_PROVIDER=aliyun)

需要以下环境变量:

```bash
export ALIYUN_SMS_ACCESS_KEY_ID="your-access-key-id"
export ALIYUN_SMS_ACCESS_KEY_SECRET="your-access-key-secret"
export ALIYUN_SMS_SIGN_NAME="your-sign-name"
export ALIYUN_SMS_TEMPLATE_CODE="SMS_xxxxxxxx"
```

运行:

```bash
export SMS_PROVIDER=aliyun
export MOBILE=13800138000

cargo run --example sms_example --features full
```

说明:

- `ALIYUN_SMS_SIGN_NAME`:短信签名
- `ALIYUN_SMS_TEMPLATE_CODE`:模板 Code
- 模板参数示例:`{"code":"123456"}`(示例内部会自动生成)

---

## Tencent 配置(SMS_PROVIDER=tencent)

需要以下环境变量:

```bash
export TENCENT_SMS_SECRET_ID="your-secret-id"
export TENCENT_SMS_SECRET_KEY="your-secret-key"
export TENCENT_SMS_APP_ID="your-sms-sdk-app-id"
export TENCENT_SMS_SIGN_NAME="your-sign-name"
export TENCENT_SMS_TEMPLATE_ID="your-template-id"
```

可选:region(默认 `ap-beijing`):

```bash
export TENCENT_SMS_REGION="ap-beijing"
# 可选值示例:ap-nanjing / ap-guangzhou / 或任意字符串(会映射为 Region::Other)
```

运行:

```bash
export SMS_PROVIDER=tencent
export MOBILE=13800138000

cargo run --example sms_example --features full
```

说明:

- 腾讯云短信的 `PhoneNumberSet` 通常需要带国家码(如 `+86...`- 示例里做了兼容:如果 `MOBILE` 不以 `+` 开头,会自动拼接 `+86`

---

## 示例环境变量一览

通用:

- `REDIS_URL`(可选,默认 `redis://127.0.0.1:6379`- `SMS_PROVIDER`(可选,默认 `aliyun`- `SMS_DEBUG`(可选,`true/1` 开启 debug 模式)
- `MOBILE`(可选,默认 `13800138000`
Aliyun:

- `ALIYUN_SMS_ACCESS_KEY_ID`
- `ALIYUN_SMS_ACCESS_KEY_SECRET`
- `ALIYUN_SMS_SIGN_NAME`
- `ALIYUN_SMS_TEMPLATE_CODE`

Tencent:

- `TENCENT_SMS_SECRET_ID`
- `TENCENT_SMS_SECRET_KEY`
- `TENCENT_SMS_APP_ID`
- `TENCENT_SMS_REGION`(可选)
- `TENCENT_SMS_SIGN_NAME`
- `TENCENT_SMS_TEMPLATE_ID`

---

## 验证码 Redis Key 约定

示例里使用:

- `redis_key_prefix = "captcha:sms:"`
- 最终 key = `captcha:sms:{mobile}`

例如:

- `captcha:sms:13800138000`

---

## 常见问题

### 1) 我不想真的发短信,怎么测试?
设置:

```bash
export SMS_DEBUG=true
```

这样 `send_captcha` 不会调用短信服务商,只会把验证码写入 Redis。

### 2) 为什么要“发送成功后”才写 Redis?
避免短信发送失败(或未到达)时仍然生成可用验证码,导致安全/体验问题。

### 3) 腾讯云手机号格式问题?
示例会自动给不带 `+` 的手机号加 `+86`。如果你要支持海外号码,建议直接传入形如 `+1...`、`+44...` 的号码。

---

## 许可证

MIT OR Apache-2.0