API 参考文档
本文档涵盖所有对外开放的 REST API,包括 OAuth 2.0 授权、微信扫码登录、密码管理、消息推送等。所有接口均基于 HTTPS,返回 JSON 格式。
不同接口使用不同的认证组合,共有三种凭证:
| 凭证 | Header | 适用接口 |
|---|---|---|
| API Key | X-API-Key: <api_key> | 用户管理、消息推送、OAuth 授权 URL 等 |
| 签名 | X-Signature / X-Timestamp | OAuth Token 端点、注册、密码重置等 |
| Bearer | Authorization: Bearer <token> | 用户信息、修改密码、退出登录等 |
使用 HMAC-SHA256 对每次请求进行签名,防止请求被篡改,有效期 5 分钟(防重放)。
time()按 key 排序后
JSON 序列化
appId+ts+body用 api_secret
计算摘要
X-Signature
// 签名生成示例 $timestamp = time(); $params = ['username' => 'alice', 'password' => 'secret']; ksort($params); $body = json_encode($params, JSON_UNESCAPED_UNICODE); $content = $appId . $timestamp . $body; $signature = hash_hmac('sha256', $content, $apiSecret); // 请求 Header 'X-API-Key': $appId 'X-Timestamp': $timestamp 'X-Signature': $signature 'Content-Type': 'application/json'
官方 PHP SDK 封装了签名、Token 验证、微信扫码等全部细节,推荐服务端接入时使用。PHP ≥ 7.4,仅依赖 ext-curl 和 ext-json,无框架依赖。
# Composer 安装 composer require uuuz/uuauth # 或手动引入 require_once __DIR__ . '/sdk/src/autoload.php';
use uuuz\Client; $client = new Client([ 'api_url' => 'https://auth.example.com', // 服务地址,末尾无斜杠 'api_key' => 'your_api_key', // API Key(必填) 'api_secret' => 'your_api_secret', // 用于签名(必填) 'jwt_secret' => 'your_jwt_secret', // 本地验证 Token(可选) 'timeout' => 30, 'ssl_verify' => true, ]);
| 参数 | 必填 | 说明 |
|---|---|---|
| api_url | 必填 | 服务器地址,不带末尾斜杠 |
| api_key | 必填 | 在管理后台「API Keys」页面创建 |
| api_secret | 必填 | 用于 HMAC 请求签名 |
| jwt_secret | 可选 | 配置后可本地验证 Token,无需网络请求 |
| timeout | 可选 | HTTP 超时(秒),默认 30 |
| ssl_verify | 可选 | 默认 true;测试环境可设 false |
api_key 或 api_secret 为空时构造函数抛出 \InvalidArgumentException。签名、时间戳等细节由 SDK 内部自动处理。用户名/邮箱/手机号 + 密码登录,失败抛出 RuntimeException。
try { $token = $client->passwordLogin('username', 'password123'); $token['access_token']; // JWT 访问令牌(2 小时有效) $token['refresh_token']; // 刷新令牌(7 天有效) $token['expires_in']; // 有效期秒数(7200) $token['user']; // 用户信息数组 } catch (\RuntimeException $e) { echo '登录失败: ' . $e->getMessage(); }
$client->register([ 'username' => 'new_user', 'password' => 'Password123', 'email' => 'user@example.com', // 可选 'phone' => '13800138000', // 可选 ]);
// 刷新 Token(refresh_token 每次刷新轮转) $newToken = $client->refreshToken($refreshToken); // 退出登录(撤销该用户所有 Refresh Token) $client->logout($accessToken);
获取授权 URL 后按环境分流:微信内静默授权,PC 展示扫码确认页。
$authInfo = $client->getAuthUrl( 'https://your-app.com/callback', // 回调地址(参数名 redirect_url) 'snsapi_userinfo', // snsapi_userinfo 或 snsapi_base 'custom_state', // 自定义 state(可选) 'login' // 场景:login / bind / password_reset ); $authInfo['session_id']; // 会话 ID,用于轮询状态 $authInfo['auth_url']; // 微信内 + snsapi_base:直接静默 OAuth $authInfo['confirm_url']; // PC / 非微信:展示扫码确认页
scope=snsapi_base 时跳转 auth_url;PC 和非微信浏览器使用 confirm_url,扫码完成后确认页显示“关闭页面”完成态并停止轮询。旧授权中心返回空 auth_url 时应升级授权中心,不要在微信内降级到人工确认页。| 场景 | 授权成功后 |
|---|---|
| login | 签发 Token,data.token 含完整令牌 |
| bind | 仅返回一次性 bind_session_id,需调用 bindWechatSession |
| password_reset | 仅返回 openid,需调用 resetPasswordByQrcode |
$status = $client->queryAuthStatus($sessionId); // status: "pending" | "authorized" | "expired" if ($status['status'] === 'authorized') { $accessToken = $status['data']['token']['access_token']; // 首次微信登录,需设置用户名 if ($status['data']['account_setup_required'] ?? false) { $client->setupAccount('my_username', null, $accessToken); } }
微信授权后跳转 redirect_url?code=xxx&state=xxx。handleCallback() 自动验证签名并换取 Token(本地 HMAC 计算,防重放 10 分钟)。
// 自动验证签名 + 换 Token(推荐) $tokenData = $client->handleCallback($_GET); // 或仅换码 $tokenData = $client->exchangeCode($_GET['code']);
// bind 场景扫码授权后 $client->bindWechatSession($accessToken, $status['data']['bind_session_id']); // 解绑 $client->unbindWechat($accessToken);
本地验证无网络请求(需配置 jwt_secret);远程验证可检测 Token 是否已被吊销。未配置 jwt_secret 时自动降级为远程验证。
// 本地验证(无网络请求,需 jwt_secret) $result = $client->validateToken($accessToken); // ['valid' => true, 'user_id' => 1, 'exp' => ..., 'jti' => 'xxx'] // 远程验证(可检查是否已被吊销) $result = $client->validateToken($accessToken, true); // ['active' => true, 'valid' => true, 'openid' => 'xxx', ...]
logout() 只吊销 Refresh Token。需实时拦截已退出用户,请用 validateToken($token, true) 远程验证。$client->sendTemplateMessage( 'user_openid', 'wx_template_id_xxx', // 微信模板 ID(与 template_key 二选一) [ 'first' => ['value' => '您的订单已发货', 'color' => '#173177'], 'keyword1' => ['value' => 'P123456789', 'color' => '#173177'], 'remark' => ['value' => '感谢您的支持!', 'color' => '#576B95'], ], 'https://your-app.com/order/123', // 跳转链接(可选) 'order_notify' // 本地模板别名(可选) );
$client->batchSendTemplateMessages( ['openid_1', 'openid_2'], '', // template_id 留空则用 template_key ['first' => ['value' => '活动提醒', 'color' => '#173177']], 'https://your-app.com/activity', 'activity_remind' ); // ['data' => ['total' => 2, 'success' => 2, 'failed' => 0]]
$client->getTemplateList(); // 模板列表(5 分钟缓存) $client->getTemplate('order_notify'); // 按别名获取单个 $client->getPushStats(7); // 最近 N 天推送统计
主客户端方法失败时直接抛出 RuntimeException;需要统一格式 {code, msg, data} 返回时用子客户端 $client->oauth()。
| 分类 | 方法 | 说明 |
|---|---|---|
| 登录认证 | passwordLogin / register / refreshToken / logout | 密码登录、注册、刷新、退出 |
| 微信扫码 | getAuthUrl / queryAuthStatus / exchangeCode / handleCallback | 授权 URL、轮询、换码、回调 |
| 微信绑定 | bindWechat / unbindWechat | 绑定、解绑 |
| Token | validateToken / verifyCallbackSign | 本地/远程验证、回调验签 |
| 账号 | setupAccount / setPassword / updateContact / getCurrentUserInfo | 初始化、设密码、联系方式、用户信息 |
| 密码 | changePassword / resetPasswordByQrcode / requestResetToken / resetPasswordByToken | 改密、扫码/令牌重置 |
| 消息 | sendTemplateMessage / batchSendTemplateMessages / getPushStats | 发送、批量、统计 |
| 模板 | getTemplateList / getTemplate | 列表、单个 |
| 用户 | getUserList / getUser / syncUsers | 列表、详情、同步 |
| V2 端点 | v2GetUsers / v2SendMessage / v2GetTemplates … | RESTful 风格接口 |
echo \uuuz\Client::version(); 错误响应描述字段为 message(不是 msg)。统一 Token 签发端点,通过 grant_type 区分登录方式。需要 API Key + 签名认证。
grant_type=password
用户名/邮箱/手机号 + 密码登录,返回 Access Token 和 Refresh Token。连续失败触发账号和 IP 级节流锁定。
| 字段 | 类型 | 必须 | 说明 |
|---|---|---|---|
| grant_type | string | 必须 | 固定值 password |
| username | string | 必须 | 用户名、邮箱或 11 位手机号 |
| password | string | 必须 | 登录密码 |
{
"access_token": "eyJhbGci...",
"token_type": "Bearer",
"expires_in": 7200,
"refresh_token": "eyJhbGci...",
"user": { "id": 1, "username": "alice", "has_wechat": true }
}grant_type=wechat
前端轮询 /api/v1/oauth/status/{session_id} 获得 code 后,调用本接口换取 JWT。授权码一次性,5 分钟内有效,且只能用于 wechat grant。
| 字段 | 类型 | 必须 | 说明 |
|---|---|---|---|
| grant_type | string | 必须 | 固定值 wechat |
| code | string | 必须 | 轮询接口返回的授权码 |
grant_type=refresh_token
用 Refresh Token 换取新的 Token 对(旧 Token 立即失效)。系统内置 Token Reuse 检测,一旦发现重放攻击,强制用户所有设备退出。
| 字段 | 类型 | 必须 | 说明 |
|---|---|---|---|
| grant_type | string | 必须 | 固定值 refresh_token |
| refresh_token | string | 必须 | 上次签发的 Refresh Token |
grant_type=client_credentials
服务端到服务端调用,不关联具体用户,返回应用级 Access Token。
| 字段 | 类型 | 必须 | 说明 |
|---|---|---|---|
| grant_type | string | 必须 | 固定值 client_credentials |
| scope | string | 可选 | 权限范围 |
验证任意 Access Token 是否有效,返回 Token 中的用户信息和有效期。可用于资源服务器在不持有 jwt_secret 的情况下验证 Token。
| 字段 | 类型 | 必须 | 说明 |
|---|---|---|---|
| token | string | 必须 | 待验证的 Access Token |
{
"code": 200,
"data": {
"active": true,
"openid": "oXxx...",
"user_info": { "id": 1, "username": "alice" },
"exp": 1753055200,
"scope": "snsapi_userinfo",
"token_type": "Bearer"
}
}授权地址按环境分流:微信内以 snsapi_base 静默授权;PC 和非微信浏览器展示扫码确认页。
authorize-url
PC:confirm_url
扫码确认
GET /status
grant=wechat
创建授权会话,返回 auth_url(微信内 snsapi_base 静默授权)、confirm_url(PC 扫码确认页)和 session_id(用于轮询状态)。
| 字段 | 类型 | 必须 | 说明 |
|---|---|---|---|
| scene | string | 可选 | login / bind / password_reset,默认 login |
| redirect_url | string | 可选 | 授权成功后的回调地址,不传则使用产品默认配置 |
| scope | string | 可选 | snsapi_userinfo(默认)或 snsapi_base |
| state | string | 可选 | 自定义状态参数,原样回传到 redirect_url |
{
"code": 200,
"data": {
"session_id": "a3f8e2...",
"confirm_url": "https://your-domain/auth/confirm/a3f8e2...",
"auth_url": "https://open.weixin.qq.com/connect/oauth2/authorize?...",
"expires_in": 180,
"scene": "login"
}
}scope=snsapi_base 时直接跳转 auth_url;PC 和非微信浏览器将 confirm_url 渲染成二维码。旧授权中心返回空 auth_url 时应升级授权中心,二维码有效期 3 分钟。建议每 1.5 秒轮询一次,直至状态变为 authorized 或 expired。授权成功时直接返回 Token,无需再调 /oauth/token。
| 状态 | 说明 |
|---|---|
| pending | 等待用户扫码 |
| authorized | 已授权,login 场景下 data.token 直接返回 JWT |
| expired | 会话过期,需重新获取授权 URL |
{
"code": 200,
"data": {
"status": "authorized",
"data": {
"openid": "oXxx...",
"token": {
"access_token": "eyJ...",
"expires_in": 7200,
"user": { "id": 1, "username": "alice" }
}
}
}
}创建本地账号,密码需符合强度要求(≥8 位,含大小写字母和数字)。注册成功后直接返回 Token 对,无需再次登录。
| 字段 | 类型 | 必须 | 说明 |
|---|---|---|---|
| password | string | 必须 | 密码(≥8 位,须含大小写字母和数字) |
| string | 可选 | 邮箱(唯一) | |
| phone | string | 可选 | 手机号(11 位,唯一) |
| nickname | string | 可选 | 昵称 |
| openid | string | 可选 | 同步绑定微信 openid |
返回当前 Token 对应的用户信息(手机号已脱敏为 138****5678)。
{ "id": 1, "nickname": "Alice",
"email": "alice@example.com", "phone": "138****5678",
"has_wechat": true, "openid": "oXxx...",
"account_setup_required": false }撤销当前用户所有 Refresh Token,所有设备同步退出。无请求 Body。Access Token 因 JWT 无状态不会立即失效,但到期后不可刷新。
微信扫码登录的新用户默认没有手机号/邮箱和密码,需通过以下接口完成初始化。
仅允许 account_setup_required=true 的用户调用,至少提供一个已验证手机号或邮箱,并同时设置密码。
| 字段 | 类型 | 必须 | 说明 |
|---|---|---|---|
| phone | string | 至少一个 | 已验证手机号 |
| string | 至少一个 | 已验证邮箱 | |
| password | string | 必须 | 设置登录密码 |
仅限未设置过密码的账号(如纯微信登录用户)。已有密码请用修改密码接口。
| 字段 | 类型 | 必须 | 说明 |
|---|---|---|---|
| password | string | 必须 | ≥8 位,须含大小写字母和数字 |
产品端自行验证手机/邮箱归属后调用本接口写入。传空字符串清空该字段,phone/email 至少传其中一个。
| 字段 | 类型 | 必须 | 说明 |
|---|---|---|---|
| phone | string | 可选 | 手机号(传 "" 清空) |
| string | 可选 | 邮箱(传 "" 清空) |
验证旧密码后修改为新密码。修改成功后强制所有设备退出,需重新登录。
| 字段 | 类型 | 必须 | 说明 |
|---|---|---|---|
| old_password | string | 必须 | 当前密码 |
| new_password | string | 必须 | 新密码(≥8 位,须含大小写字母和数字,不能与旧密码相同) |
由产品端担保用户身份后申请重置令牌,返回一次性令牌(默认 5 分钟有效)。防枚举:用户名不存在也返回成功。同一用户名每小时最多申请 3 次。
| 字段 | 类型 | 必须 | 说明 |
|---|---|---|---|
| username | string | 必须 | 用户名 / 邮箱 / 手机号 |
{ "code": 200,
"data": { "reset_token": "uuuz_rst_xxx...", "expires_in": 300 } }使用申请到的 reset_token 重置密码。令牌一次性使用,且必须与申请时的应用一致。成功后强制所有设备退出。
| 字段 | 类型 | 必须 | 说明 |
|---|---|---|---|
| reset_token | string | 必须 | 申请重置令牌返回的 token |
| new_password | string | 必须 | 新密码(≥8 位,须含大小写字母和数字) |
用户通过 scene=password_reset 扫码验证身份(轮询获得 openid)后,用 session_id + 新密码重置。要求该微信已绑定账号。
| 字段 | 类型 | 必须 | 说明 |
|---|---|---|---|
| session_id | string | 必须 | 扫码会话 ID |
| openid | string | 必须 | 扫码得到的 openid |
| new_password | string | 必须 | 新密码(≥8 位,须含大小写字母和数字) |
已登录用户通过 scene=bind 扫码获得 openid 后,调用本接口完成绑定。一个微信只能绑定一个账号。
| 字段 | 类型 | 必须 | 说明 |
|---|---|---|---|
| openid | string | 必须 | 扫码得到的 openid |
解除当前用户绑定的微信。无请求 Body。
分页返回微信公众号用户列表。
| 字段 | 类型 | 必须 | 说明 |
|---|---|---|---|
| page | int | 可选 | 页码,默认 1 |
| limit | int | 可选 | 每页数量,默认 20 |
返回用户总数、已关注/已取关、绑定本地账号数等聚合统计。
根据 openid 返回单个微信用户的详细信息。
从微信服务器拉取公众号关注者列表并同步到本地数据库。
根据 openid 数组批量获取用户信息,单次最多 100 个。
| 字段 | 类型 | 必须 | 说明 |
|---|---|---|---|
| openids | array | 必须 | openid 字符串数组(最多 100) |
向指定 openid 发送微信模板消息。可用 template_id(微信模板 ID)或 template_key(本地模板别名)。
| 字段 | 类型 | 必须 | 说明 |
|---|---|---|---|
| openid | string | 必须 | 接收者 openid |
| template_key | string | 必须 | 模板标识(或 template_id) |
| data | object | 必须 | 模板变量键值对 |
| url | string | 可选 | 点击消息跳转地址 |
向多个 openid 批量发送模板消息,支持异步队列处理。
| 字段 | 类型 | 必须 | 说明 |
|---|---|---|---|
| openids | array | 必须 | 接收者 openid 数组 |
| template_key | string | 必须 | 模板标识 |
| data | object | 必须 | 模板变量键值对 |
返回所有已启用的消息模板及其字段配置。
根据模板标识返回模板详情和字段定义。
返回产品配置、支持的场景和 scope。
返回 Redis、MySQL、磁盘状态。HTTP 200=健康,503=不健康。
返回 OIDC 元数据(authorization_endpoint、token_endpoint 等)。
config/route.php 或联系管理员。