Phira-mp+ (PMP) 聊天消息鉴权插件。客户端硬编码密钥,服务端插件验证, 会话级鉴权——每个 TCP 连接独立授权,断开后自动清除。
Phira 客户端 (硬编码 KEY) PMP 服务端
│ │
│ connect(token) ─────────────► UserConnect (+1 conn)
│ │
│ POST /api/chat-auth │
│ {"user_id": 123, │ PMP 插件
│ "key": "secret"} ────────► ├─ 验证 key == config.auth_key
│ ├─ 标记该连接已授权
│ └─ 返回 {ok: true}
│ │
│ chat("hello") ─────────────► handle_chat()
│ ├─ call_plugin_api("is_authorized")
│ ├─ conn>0 + 已授权? → 广播
│ └─ 否则 → 拒绝
│ │
│ disconnect ────────────────► UserDisconnect (-1 conn)
│ └─ conn=0 → 清除授权
| 文件 | 说明 |
|---|---|
src/lib.rs |
WASM 插件源码 |
Cargo.toml |
Rust 项目配置 |
chat-auth.capabilities.json |
权限声明(config, http, room.manage) |
config.example.json |
插件配置示例 |
server-hook.patch |
PMP 服务端 handle_chat 修改说明 |
deps/Phira-mp-plus |
Phira-mp-plus 子模块(提供 WIT + SDK) |
# 克隆(含子模块)
git clone --recursive https://github.com/FireflyF09/Chat-Auth-PMP.git
cd Chat-Auth-PMP
# 编译 WASM
cargo build --target wasm32-unknown-unknown --release
# 打包组件
wasm-tools component new \
target/wasm32-unknown-unknown/release/chat_auth.wasm \
-o chat-auth.component.wasmcp chat-auth.component.wasm /path/to/phira-mp-plus/plugins/chat-auth.wasm
cp chat-auth.capabilities.json /path/to/phira-mp-plus/plugins/mkdir -p /path/to/phira-mp-plus/data/plugins/chat-auth
cat > /path/to/phira-mp-plus/data/plugins/chat-auth/config.json <<EOF
{"auth_key": "my-secret-key"}
EOF按照 server-hook.patch 修改 phira-mp-plus-server/src/session_actor.rs,
在 handle_chat 中添加鉴权检查。
# PMP 控制台
plugin reload chat-auth在 Phira 客户端的 mp/panel.rs 中,connect() 认证成功后调用插件 HTTP API:
const CHAT_AUTH_KEY: &str = "my-secret-key"; // 与插件配置一致
fn connect(&mut self) {
let Some(token) = get_data().tokens.as_ref().map(|it| it.0.clone()) else {
show_message(mtl!("connect-must-login")).error();
return;
};
let addr = get_data().config.mp_address.clone();
let auth_key = CHAT_AUTH_KEY.to_string();
self.connect_task = Some(Task::new(async move {
let client = Client::new(TcpStream::connect(addr.clone()).await?).await?;
client.authenticate(token).await
.with_context(|| anyhow!(mtl!("connect-authenticate-failed")))?;
// ── 插件鉴权 ──
let user_id = client.me().map(|u| u.id).unwrap_or(0);
if user_id > 0 {
let http_port = "8080"; // PMP HTTP 默认端口
let http_addr = addr.split(':').next().unwrap_or("127.0.0.1").to_string();
let url = format!("http://{http_addr}:{http_port}/api/chat-auth");
let body = serde_json::json!({"user_id": user_id, "key": auth_key});
// 使用 reqwest 或 ureq 发送 POST
// ...
}
Ok(client)
}));
}- 密钥硬编码在客户端二进制中,可被逆向
- 此方案适用于私服防止未授权用户聊天
- 连接断开即清除授权,重连需重新鉴权
- 如需更高安全性,应使用非对称签名 + 挑战响应