⚠️ 本页面为历史归档文档,最新文档请访问 /docs

🧩 UM 分组与策略系统 v1.1

← API 文档 🎯 战略架构 👕 行业模块 🔌 插件规范 管理后台

核心特性 必读

UM v1.1 引入了三级权限 + 6 大登录策略 + 灵活配置中心,解决 B 端商家入驻场景下"单点登录 vs 独立登录"的灵活配置问题。

三大创新点

6 大登录策略

策略 标识 适用场景
独立登录 independent 敏感应用、支付系统。每个 app 独立鉴权。
分组 SSO group_sso 自营产品线、商家多应用。同组共享登录态。
全局 SSO global_sso 企业内部系统、单一品牌全线产品。登录即全平台免登。
单设备登录 single_device 交易系统、VIP 内容平台。同时仅 1 个设备在线。
多设备限额 multi_device SaaS 工具。允许 N 个设备同时在线,0=不限制
IP 绑定 ip_bound 后台管理系统、高安全场景。IP 变化需重新认证。

三级权限模型

超管 / 客户(系统购买方) — 拥有所有权限
├── 可见:全部应用 + 全部分组
├── 可改:全部 27 项配置
└── 可注册/删除权限项

B 端用户(商家/加盟商/代理商) — 受限配置
├── 角色模板决定可改范围
├── 仅 app_scope + group_scope 内应用
└── 默认 25 项可改,2 项仅客户可改(cookie 域/TTL)

C 端用户(终端用户) — 只读 + 个人偏好
├── 查看自己的设备/会话
└── um_user_preference 表达个人偏好

预置角色(um_b_roles

角色 代码 权限规则
超级管理员 super_admin {"*":"*"} 全部
客户管理员 customer {"policy_option":"rw","app_field":"rw"}
商家 merchant {"policy_option":"rw","app_field":"r","own_apps":"rw"}
加盟商 franchise 同 merchant,可配子账号
代理商 agent {"policy_option":"r","app_field":"r"} 只读+统计
只读运营 readonly {"*":"r"}

灵活配置中心(ConfigCenter核心

所有可配置项必须在 um_perm_registry 中注册。配置合并优先级:

应用级 override  >  分组级 override  >  perm_registry 默认值

已注册的 27 项可配置项

perm_key 类型 默认 范围 B端
📦 策略开关(6 项)
policy.independent.allow bool 1 -
policy.group_sso.allow bool 1 -
policy.global_sso.allow bool 1 -
policy.single_device.allow bool 1 -
policy.multi_device.allow bool 1 -
policy.ip_bound.allow bool 1 -
🔧 策略子选项(6 项)
multi_device.max_devices int 0 0~999
single_device.kick_mode enum kick_old kick_old/reject_new
ip_bound.change_action enum kick kick/warn/force_relogin
ip_bound.check_interval int 60 10~3600
group_sso.cookie_domain string .yunjii.cn - 仅客户
group_sso.cookie_ttl int 604800 60~2592000 仅客户
🔐 通用登录配置(7 项)
login.max_attempts int 5 0~999
login.lock_minutes int 30 0~9999
login.session_timeout int 0 0~86400
login.allow_simultaneous bool 1 -
login.password_min_length int 6 4~32
login.password_complex enum letter_digit any/letter_digit/strong
independent.need_captcha bool 0 -
📱 应用级配置(8 项)
app.allow_register bool 1 -
app.allow_oauth bool 1 -
app.allow_phone_login bool 1 -
app.allow_email_login bool 1 -
app.allow_password_login bool 1 -
app.allow_sms_code_login bool 1 -
app.token_expire_hours int 168 1~8760
app.show_in_user_center bool 1 -
新增策略项无需改代码:在 um_perm_registry INSERT 一行即可,B 端商家控制台和客户后台会自动显示该选项。

新 API 接口

act=check_sso - SSO 状态检测

检测用户是否已在 SSO 中心登录。已登录直接返回 Token。

GET /um/connect.php?act=check_sso&appid=1012&appkey=xxx

成功响应:

{
    "code": 0,
    "logged_in": true,
    "token": "eyJ0eXAiOiJKV1Qi...",
    "scope": "yunjii",
    "scope_type": "group",
    "user": { "id": 10086, "nickname": "demo" }
}

act=sso_logout - SSO 统一登出

登出当前作用域内所有 Token(单设备/分组/全局)。

POST /um/connect.php?act=sso_logout
Authorization: Bearer {token}

act=policy - 查询应用登录策略

供前端 SDK 动态获取当前应用的策略配置。

GET /um/connect.php?act=policy&appid=1012&appkey=xxx
{
    "code": 0,
    "policy": "group_sso",
    "group_key": "yunjii",
    "all_options": {
        "multi_device.max_devices": 0,
        "login.max_attempts": 5,
        "ip_bound.change_action": "kick",
        ...
    }
}

Token 多实例机制

从 v1 单 Token 升级为 v2 多实例:um_user_token 表存储按 scope 分组的多 Token。

字段 说明
scope 作用域:global / group_xxx / app_xxx
scope_type global / group / app
device_id 设备指纹(single/multi_device 必填)
login_ip 登录 IP(ip_bound 必填)
ip_bound 是否 IP 绑定
expire_at 过期时间
v1/v2 兼容:系统自动检测 um_user_token 表是否存在;不存在则回退到 v1(um_user.token 单字段)。

设备指纹与登录设备记录

DeviceFingerprint::generate() 基于 UA + IP + Accept-Language 生成设备 ID。
um_user_device 表记录每个设备的登录信息:

C 端用户可以在"我的设备"页面查看并主动踢出某个设备。

数据表

表名 说明
um_app_group 应用分组(含 owner_id/scope_type
um_app_group_rel 应用↔分组关联(多对多)
um_user_token Token 多实例表(v2 核心)
um_user_device 用户设备记录
um_b_users B 端用户(商家/加盟商/代理商)
um_b_roles B 端角色模板(已预置 6 个)
um_perm_registry 权限注册表(27+ 项可配置)
um_config_override 配置项覆盖表(应用/分组级别)
um_login_attempt 登录尝试记录(用于锁定/限流)
um_user_preference C 端用户偏好

核心代码类(um/auth.php

职责
LoginPolicy 策略枚举 + 描述 + needsGroup/needsDevice/needsIpBound 判断
Token JWT 编码/解码 + v1/v2 兼容 + 多策略 Token 生成与验证
PolicyResolver 根据 appid 解析最终策略:app > group > registry 默认
DeviceFingerprint 设备指纹生成与解析
BUserAuth B 端登录态管理 + 权限判断 can() / ownsApp() / ownsGroup()
ConfigCenter 注册表加载 + override 合并 + 值校验

管理界面入口

入口 URL 用途
管理员后台 - 应用管理 /um/admin/apps.php 创建/编辑应用、设置分组、覆盖策略
管理员后台 - 应用分组 /um/admin/groups.php 管理分组、设置分组级策略
管理员后台 - B 端用户 /um/admin/b_users.php 创建商家账号、分配 app_scope/group_scope
管理员后台 - 权限注册表 /um/admin/registry.php 查看/调整每个配置项的 B 端可改/只读
B 端商家控制台 /um/b_console.php 商家登录后配置自己的应用策略
B 端登录入口 /um/b_login.php 商家账号登录

典型应用场景示例

场景 1:云集旗下产品线 SSO

// 在管理后台创建分组
INSERT INTO um_app_group (group_key, name, login_policy, policy_config)
VALUES ('yunjii', '云集产品线', 'group_sso', '{"max_devices":0}');

// 把多个 app 加入分组
UPDATE um_apps SET group_id=2 WHERE appid IN (1001, 1002, 1003, 1005);

// 效果:用户登录任意一个 app,同分组所有 app 自动登录
// 设备数无限制(max_devices=0)
// Cookie 域:.yunjii.cn(主域下所有子域共享)

场景 2:交易系统 - 单设备 + IP 绑定

// 创建分组 "trading"
INSERT INTO um_app_group (group_key, name, login_policy, policy_config)
VALUES ('trading', '交易系统', 'single_device', '{}');

// 应用表覆盖策略(再叠加 IP 绑定)
UPDATE um_apps SET login_policy='ip_bound' WHERE appid=2001;
// policy_config: {"ip_bound":true,"change_action":"kick"}

// 效果:
// 1. 用户在新设备登录,旧设备立即被踢
// 2. IP 变化立即踢出,需重新登录

场景 3:SaaS 工具 - 多设备限额 3 端

// B 端商家在控制台里调整 max_devices = 3
$cc = new ConfigCenter();
$cc->set('multi_device.max_devices', 3, appid: 3001, bUserId: 5);

// 效果:用户最多 3 个设备同时在线
// 第 4 个设备登录时,自动踢出最早的第 1 个

代码调用示例

PHP 端生成带策略的 Token

require_once 'auth.php';

$token = new Token();
$result = $token->generateWithPolicy(
    userId: 10086,
    openid: 'oxxx',
    type: 'wx',
    appid: 1001,
    options: [
        'policy'      => 'group_sso',
        'group_key'   => 'yunjii',
        'device_id'   => DeviceFingerprint::generate(),
        'device_info' => DeviceFingerprint::info(),
        'max_devices' => 0,    // 0 = 不限制
        'ip_bound'    => true, // 强 IP 绑定
    ]
);

读取最终生效的配置

$cc = new ConfigCenter();
$opts = $cc->getEffective(1001);
echo $opts['multi_device.max_devices'];   // 0
echo $opts['login.max_attempts'];         // 5
echo $opts['ip_bound.change_action'];     // 'kick'

判断 B 端权限

$bAuth = new BUserAuth();
if ($bAuth->can('multi_device.max_devices', 'w')) {
    // 当前 B 端用户可修改最大设备数
}
if ($bAuth->ownsApp(1001)) {
    // 当前 B 端用户管辖 appid=1001
}

迁移说明

  1. 执行 um/migrate_sso.sql 创建 3 张表 + 2 个 ALTER
  2. 执行 um/migrate_rbac.sql 创建 6 张表 + 1 个存储过程 + 27 项配置注册
  3. 无侵入:v1 单 Token 自动兼容,不需要数据迁移