# Meituan C User Auth

> 美团C端用户Agent认证工具。为需要美团用户身份的 Skill（如发券、查订单等）提供手机号验证码登录认证，管理用户Token，实现“一次认证、持续有效”。当其他 Skill 需要校验用户身份、获取用户Token时，作为前置认证模块调用。触发词：美团登录、用户认证、手机号验证、发送验证码、获取Token、切换账号、退出登录。

- Skill: `leoyeai-openclaw-master-skills/meituan-c-user-auth` (Agent Skill, multi-file: 5 files)
- Install (CLI): `npx skillmds@latest add leoyeai-openclaw-master-skills/meituan-c-user-auth`
- Raw SKILL.md: https://api.skillmd.com/api/skills/leoyeai-openclaw-master-skills/meituan-c-user-auth/raw
- Safety review: pending
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: AI & ML
- Author: LeoYeAI (https://skillmd.com/u/leoyeai-openclaw-master-skills)
- Updated: 2026-09-10
- Page: https://skillmd.com/skills/leoyeai-openclaw-master-skills/meituan-c-user-auth

---


# 美团C端用户认证工具

---

## 环境准备

**macOS：**
```bash
PYTHON=~/Library/Application\ Support/xiaomei-cowork/Python311/python/bin/python3
SCRIPT="$CLAUDE_CONFIG_DIR/skills/meituan-c-user-auth/scripts/auth.py"
```

**Windows（Git Bash）：**
```bash
PYEXE="$(cygpath "$APPDATA")/xiaomei-cowork/Python311/python/python.exe"
SCRIPT="$CLAUDE_CONFIG_DIR/skills/meituan-c-user-auth/scripts/auth.py"
# 后续命令将 $PYTHON 替换为 "$PYEXE"
```

**Linux / 其他 Agent 环境：**
```bash
# 使用系统 Python 3（或自定义路径）
PYTHON=python3
SCRIPT="$CLAUDE_CONFIG_DIR/skills/meituan-c-user-auth/scripts/auth.py"
# 如需自定义 Token 存储路径（沙箱/隔离场景）：
export XIAOMEI_AUTH_FILE=/tmp/my_auth_tokens.json
```

> ⚠️ `$CLAUDE_CONFIG_DIR` 在 macOS 路径含空格，**SCRIPT 变量赋值和使用时均需加双引号**。

## 时区检查（必须执行）

本 Skill 调用的所有接口均以**北京时间（UTC+8）**为准。

```bash
# 检查本地时区
date +%Z
```

**处理规则**：
- 如果时区已是 `CST` / `Asia/Shanghai` / `UTC+8` → 直接使用系统时间，无需转换
- 如果时区是 `UTC` 或其他时区 → **处理所有命令时需将时间转换到北京时间（UTC+8）再使用**

---

## 命令一览

| 命令 | 说明 | 是否调用远程接口 |
|------|------|----------------|
| `version-check` | 检查本地 Skill 版本，与广场版本对比 | ⚡ 本地为主，有远程源时才请求 |
| `terms-check` | 检查用户是否已接受服务协议 | ❌ 本地只读 |
| `terms-accept` | 用户接受服务协议 | ❌ 本地操作 |
| `terms-decline` | 用户拒绝服务协议 | ❌ 本地操作 |
| `status` | 本地检查 Token 是否存在 | ❌ 本地只读 |
| `token-verify` | 调用服务端校验 Token 真实有效性 | ✅ 调用接口 |
| `send-sms --phone <手机号>` | 发送短信验证码 | ✅ 调用接口 |
| `verify --phone <手机号> --code <验证码>` | 验证验证码，写入 Token | ✅ 调用接口 |
| `logout` | 退出登录，user_token 置空（保留 device_token） | ❌ 本地操作 |

---

## 版本检查（每次对话首次使用时执行）

> 每次对话中**第一次**使用本 Skill 时执行，同一对话内无需重复。

**实现原理**：通过 WebFetch 访问 clawhub.ai 上的公开版本页面，从页面内容中提取 `version:` 字段，再传给脚本进行对比。

### 步骤一：获取远程版本号

```bash
# 使用 WebFetch 工具访问以下 URL，提取页面中 version 字段
# URL: https://clawhub.ai/meituan-zhengchang/meituan-c-user-auth
```

从返回内容中找到 `version: "x.y.z"` 或 `"version": "x.y.z"` 字段，提取版本号（如 `1.0.0-SNAPSHOT`）。若页面无法访问或未找到版本字段，跳过版本对比。

### 步骤二：调用脚本进行版本对比

```bash
# 将上一步提取到的远程版本号通过 --remote 参数传入
$PYTHON "$SCRIPT" version-check --remote <远程版本号>

# 示例：
$PYTHON "$SCRIPT" version-check --remote "1.0.0-SNAPSHOT"

# 若上一步获取失败，不传 --remote，脚本会静默跳过对比
$PYTHON "$SCRIPT" version-check
```

**处理逻辑**：
- `up_to_date: true` → 继续执行，无需提示
- `up_to_date: false` → 提示用户：
  ```
  本地 Skill 版本较旧（当前 x.y.z，最新 a.b.c），建议前往以下地址更新以获取最新能力：
  https://clawhub.ai/meituan-zhengchang/meituan-c-user-auth
  继续使用旧版本也可正常登录。
  ```
- `up_to_date: null`（未传入远程版本）→ 静默跳过，不影响正常流程

---

## 服务协议确认（每次调用前必须检查）

> **法律合规要求**：在使用本 Skill 的任何功能前，必须确认用户已阅读并接受《Skill 服务使用规则》。

**协议文档位置：**`references/terms-of-service.md`

### 协议检查命令

```bash
# 检查用户是否已接受协议
$PYTHON "$SCRIPT" terms-check
```

**返回结果：**
- `terms_accepted: true` → 用户已接受，可继续使用认证流程
- `terms_accepted: false` → 用户未接受，需要引导用户阅读并确认

### 协议未接受时的处理流程

```
┌──────────────────────────────────────────────────────────────────┐
│  用户未接受协议时，引导完成协议确认：    │
│                                            │
│  1. 展示官方声明并告知《Skill服务使用规则》概要：              │
│                                            │
│  "本Skill为美团官方开发并提供，请您放心使用。                  │
│   使用前请参见并同意《Skill服务使用规则》"       │
│                                            │
│  2. 询问用户并合并接受流程：              │
│  "请问您是否阅读并接受《Skill服务使用规则》？          │
│   回复 '是' 或 '接受' 表示接受，        │
│   回复 '否' 或 '拒绝' 表示不接受，      │
│   回复 '查看全文' 查看完整规则内容。    │
│   您也可以直接输入手机号，视为接受规则   │
│   并开始登录认证。"                      │
│                                            │
│  3. 用户输入'查看全文'时：                │
│   [使用Read工具读取并展示references/terms-of-service.md全文]│
│   → 展示完成后重新询问是否接受            │
│                                            │
│  4. 用户接受后（回复'是'/接受 或 输入手机号）： │
│   $PYTHON "$SCRIPT" terms-accept           │
│   → 如果用户直接输入手机号，跳过询问直接发送验证码 │
│   → 如果用户回复'是'/接受'，再请用户输入手机号│
│                                            │
│  5. 用户拒绝后执行：                         │
│   $PYTHON "$SCRIPT" terms-decline         │
│   → 告知用户无法使用服务，结束对话       │
└──────────────────────────────────────────────────────────────────┘
```

> **重要：**用户接受协议后，`terms_accepted` 状态会持久化存储在本地 Token 文件中，
> 同一设备后续调用无需重复确认。如需撤销接受，可使用 `terms-decline` 命令。

---

## 标准认证流程（每次调用必须按此步骤执行）

```
┌──────────────────────────────────────────────────────────────────┐
│  第一步（协议检查）：检查服务协议确认状态     │
│  $PYTHON "$SCRIPT" terms-check             │
│  ├── terms_accepted: true                  │
│  │   → 进入第二步（Token 校验）           │
│  └── terms_accepted: false                 │
│      → 执行协议确认流程（见上文）        │
└──────────────────────────────────────────────────────────────────┘
          ↓
┌──────────────────────────────────────────────────────────────────┐
│  第二步（Token 校验）：调用远程接口校验 Token     │
│  $PYTHON "$SCRIPT" token-verify              │
│  ├── valid: true  → 告知用户已登录         │
│  │           (手机号 phone_masked)          │
│  │           返回 user_token，流程结束      │
│  └── valid: false → 进入第三步            │
└──────────────────────────────────────────────────────────────────┘
          ↓（Token 无效或不存在）
┌──────────────────────────────────────────────────────────────────┐
│  第三步：引导用户输入手机号                 │
│  "请输入您的美团账号手机号："               │
│  等待用户输入                              │
└──────────────────────────────────────────────────────────────────┘
          ↓
┌──────────────────────────────────────────────────────────────────┐
│  第四步：发送短信验证码                     │
│  $PYTHON "$SCRIPT" send-sms --phone <手机号>  │
│  ├── 成功 → 告知用户：                     │
│  │   "验证码已发送至手机 xxx****xxxx，     │
│  │    请打开手机短信查看验证码，            │
│  │    60秒内有效"                         │
│  ├── code=20010（安全验证）→ 见下方分支    │
│  └── 其他失败 → 告知原因（见错误码说明）   │
└──────────────────────────────────────────────────────────────────┘
          ↓（当 code=20010 时的安全验证分支）
┌──────────────────────────────────────────────────────────────────┐
│  安全验证分支：引导用户完成身份校验         │
│  脚本输出 JSON 示例：                       │
│  {                                         │
│    "error": "SMS_SECURITY_VERIFY_REQUIRED",│
│    "redirect_url": "https://..."           │
│  }                                         │
│                                            │
│  ⚠️ 必须从 JSON 输出的 redirect_url 字段   │
│     取值，禁止自行拼装或猜测跳转链接！       │
│  ⚠️ 若 redirect_url 为空字符串，提示用户    │
│     "安全验证链接获取失败，请稍后重试"       │
│                                            │
│  redirect_url 不为空时提示用户：            │
│  "为保障账号安全，您需要先完成一次身份验证。 │
│   请点击以下链接，在页面中完成验证：         │
│   <redirect_url 字段的值>                  │
│   完成验证后，系统会自动发送短信验证码，     │
│   请留意手机短信，然后将验证码告诉我。"     │
│                                            │
│  等待用户反馈已完成验证后，重新执行第四步   │
│  （重新发送验证码，不需要用户再次输入手机号）│
└──────────────────────────────────────────────────────────────────┘
          ↓
┌──────────────────────────────────────────────────────────────────┐
│  第五步：等待用户输入验证码                 │
│  "请输入您收到的6位验证码："                │
│  等待用户输入                              │
└──────────────────────────────────────────────────────────────────┘
          ↓
┌──────────────────────────────────────────────────────────────────┐
│  第六步：验证验证码                         │
│  $PYTHON "$SCRIPT" verify \                  │
│    --phone <手机号> --code <验证码>         │
│  ├── 成功 → "认证成功，xxx****xxxx 已登录"  │
│  │           user_token 已自动写入          │
│  │           返回 user_token 供调用方使用   │
│  └── 失败 → 告知原因，提示重新发送或重试   │
└──────────────────────────────────────────────────────────────────┘
```

---

## 错误码说明（告知用户时使用友好描述）

| 错误码 | 涉及接口 | 友好提示 |
|--------|---------|---------|
| 20002 | 发送验证码 | 验证码已发送，请等待1分钟后再试 |
| 20003 | 验证验证码 | 验证码错误或已过期（60秒有效），请重新获取 |
| 20004 | 发送/验证 | 该手机号未注册美团，请先下载美团APP完成注册 |
| 20005 | 校验Token | 登录状态已过期，需要重新认证 |
| 20006 | 发送验证码 | 该手机号今日发送次数已达上限（最多5次），请明天再试 |
| 20007 | 发送验证码 | 短信发送量已达今日上限，请明天再试 |
| 20010 | 发送验证码 | 需要完成安全验证，请按提示访问验证链接，完成后留意手机短信 |
| 99997 | 全部 | 系统繁忙，请稍后重试 |
| 99998 | 全部 | 未知异常，请稍后重试 |
| 99999 | 全部 | 参数错误，请检查手机号格式是否正确 |

---

## 供其他 Skill 调用的约定

在调用方的 SKILL.md 中写：

```markdown
## 前置认证
1. 调用 meituan-c-user-auth Skill，按标准认证流程执行
2. 获取有效 user_token
3. 携带 user_token 调用业务接口
4. 若业务接口返回 Token 无效错误，重新触发认证流程
```

---

## 注意事项

1. **Token 校验使用 `token-verify`**（远程接口），而非 `status`（仅本地存在性检查）
2. **验证码60秒有效**，1分钟内不能重复发送，发送前提醒用户
3. **Token 有效性以服务端校验为准**：`token-verify` 返回 `valid: false` 时才需要重新认证，不在本地推算过期时间，不向用户提示 Token 有效期
4. **user_token 不要在对话中显示**，仅传递给业务接口
5. **退出/切换账号**：执行 `logout` 命令清除 Token
6. **device_token 不要在对话中展示**：device_token 是设备唯一标识，属于内部字段，正常交互中不得向用户输出；仅在排查登录问题时，且用户明确要求查看时，才可展示
7. **安全验证（20010）处理**：当 send-sms 返回 `error=SMS_SECURITY_VERIFY_REQUIRED` 时，**必须从脚本 JSON 输出的 `redirect_url` 字段取值作为跳转链接**，禁止自行拼装或猜测链接；若 `redirect_url` 为空则提示用户稍后重试；引导用户点击该链接完成安全验证后，**重新调用 send-sms**（无需用户再次输入手机号）；安全验证后的短信由后端自动触发，用户直接输入收到的验证码即可
8. **法律合规要求**：在使用任何功能前，必须检查并确认用户已接受《Skill 服务使用规则》（使用 `terms-check` 命令）
9. **展示协议全文时必须展示原文**：当用户要求查看《Skill 服务使用规则》全文时，必须使用 Read 工具读取 `references/terms-of-service.md` 原文展示，不得精简、概括或修改内容

---

## API 信息摘要

| 接口 | 路径 | 方法 | 关键请求字段 |
|------|------|------|------------|
| 发送验证码 | `/eds/claw/login/sms/code/get` | POST | `mobile`, `uuid`（device_token） |
| 验证验证码 | `/eds/claw/login/sms/code/verify` | POST | `mobile`, `smsVerifyCode`, `uuid`（device_token） |
| 校验 Token | `/eds/claw/login/token/verify` | POST | `?token=<token>` (Query) |

> 当前使用**线上外网**域名：`https://peppermall.meituan.com`

完整接口文档见 `references/api-config.md`

