如何在Y.js中阻止指定字段被修改?角色权限控制场景
解决方案:基于Y.js + y-socket.io的角色权限控制
针对manager角色无法修改title和editors字段的需求,核心要在服务器端做权限拦截(客户端限制仅为体验优化),具体实现如下:
一、服务器端核心校验(安全保障)
y-socket.io的服务器可以通过beforeHandleUpdate钩子拦截客户端的更新请求,校验操作是否符合角色权限:
const { Server } = require('socket.io'); const { setupWSConnection } = require('y-socket.io/dist/server'); const Y = require('yjs'); const io = new Server(3000, { cors: { origin: '*' } }); io.on('connection', (socket) => { // 从连接认证中获取用户角色(建议用JWT等安全方式传递) const { role } = socket.handshake.auth; setupWSConnection(socket, io, { // 初始化文档数据 async loadDoc(docName, doc) { const project = { editors:{'me@stack.com':'owner', 'they@stack.com':'manager' }, title:'myStackProject', article:'I love to ask questions' }; const yProject = doc.getMap('project'); yProject.set('editors', new Y.Map(project.editors)); yProject.set('title', project.title); yProject.set('article', project.article); }, // 拦截更新请求,做权限校验 async beforeHandleUpdate(doc, update, origin) { if (role === 'manager') { // 创建临时文档解析更新内容 const tempDoc = new Y.Doc(); Y.applyUpdate(tempDoc, update); const tempProject = tempDoc.getMap('project'); // 检查是否修改了受限字段 const changedKeys = Array.from(tempProject.keys()); if (changedKeys.includes('title') || changedKeys.includes('editors')) { return false; // 拒绝更新 } } return true; // 允许合法更新 } }); });
二、客户端辅助限制(体验优化)
在客户端根据角色禁用受限字段的编辑入口,同时监听文档变化,防止绕过UI限制的操作:
import * as Y from 'yjs'; import { WebsocketProvider } from 'y-websocket'; const doc = new Y.Doc(); const provider = new WebsocketProvider('ws://localhost:3000', 'project-doc', doc); const yProject = doc.getMap('project'); // 实际从登录状态获取当前用户角色 const currentRole = 'manager'; // UI层面禁用编辑 if (currentRole === 'manager') { document.getElementById('title-input').disabled = true; document.getElementById('editors-container').style.pointerEvents = 'none'; } // 监听文档变化,非法操作时提示并同步正确数据 yProject.observe((event) => { if (currentRole === 'manager') { const changedKeys = Array.from(event.keysChanged); if (changedKeys.includes('title') || changedKeys.includes('editors')) { alert('您没有权限修改该字段'); provider.sync(); // 拉取服务器端的正确数据覆盖本地 } } });
关键注意事项
- 服务器端校验是核心:客户端限制可被篡改,只有服务器端拦截才能真正保障数据安全。
- 角色认证要安全:用户角色需通过JWT、session等可靠方式传递,避免伪造。
- 解析更新的方式:示例用临时文档解析,也可以使用
Y.decodeUpdate做更高效的操作解析。
内容的提问来源于stack exchange,提问作者Jane Jacek
相关产品推荐
相关产品推荐

