权限管理面临的挑战
- 不同子应用间权限数据同步:各子应用独立开发维护,权限数据更新频率、格式可能不同,导致同步困难。例如,子应用A基于角色权限,子应用B基于资源权限,数据结构差异大。
- 权限校验逻辑的统一与差异化:既要保证主应用与子应用整体权限校验逻辑一致,又要允许子应用根据自身业务定制特殊校验规则。比如,主应用统一规定某些页面只有管理员可访问,但子应用可能对特定功能有更细粒度权限控制。
优化与扩展方案
技术选型
- 状态管理:选用Vuex管理主应用和子应用的权限状态,保证状态一致性和可维护性。
- 通信:使用微前端框架提供的通信机制(如qiankun的postMessage通信方式),实现子应用与主应用间权限数据交互。
- 接口管理:采用HTTP接口进行权限数据获取和更新,便于不同应用间交互。
架构设计
- 主应用:维护全局权限配置,提供统一权限校验入口。设置中央权限服务,负责管理所有子应用权限数据。
- 子应用:从主应用获取权限数据,在本地缓存并按需更新。在子应用内建立本地权限校验模块,优先本地校验,特殊情况调用主应用校验接口。
关键代码片段或伪代码描述
- 主应用Vuex模块(权限部分)
// store/modules/permission.js
const state = {
globalPermissions: []
};
const mutations = {
SET_GLOBAL_PERMISSIONS(state, permissions) {
state.globalPermissions = permissions;
}
};
const actions = {
async fetchGlobalPermissions({ commit }) {
const response = await axios.get('/api/global-permissions');
commit('SET_GLOBAL_PERMISSIONS', response.data);
}
};
export default {
namespaced: true,
state,
mutations,
actions
};
- 主应用提供权限校验接口
// server.js (假设使用Node.js + Express)
const express = require('express');
const app = express();
app.get('/api/check-permission', (req, res) => {
const { userId, permission } = req.query;
// 这里从数据库或缓存获取用户权限并校验
const userPermissions = getPermissionsByUserId(userId);
if (userPermissions.includes(permission)) {
res.send(true);
} else {
res.send(false);
}
});
const port = 3000;
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});
- 子应用获取并校验权限
// 子应用Vuex模块(权限部分)
import { mapActions } from 'vuex';
const state = {
localPermissions: []
};
const mutations = {
SET_LOCAL_PERMISSIONS(state, permissions) {
state.localPermissions = permissions;
}
};
const actions = {
async syncPermissions({ commit }) {
// 通过微前端通信获取主应用权限数据
const globalPermissions = await window.parent.postMessage({ type: 'get-global-permissions' }, '*');
commit('SET_LOCAL_PERMISSIONS', globalPermissions);
},
checkPermission({ state }, permission) {
return state.localPermissions.includes(permission);
}
};
export default {
namespaced: true,
state,
mutations,
actions
};
// 在子应用组件中使用
export default {
methods: {
...mapActions('permission', ['syncPermissions', 'checkPermission']),
async someMethod() {
await this.syncPermissions();
const hasPermission = this.checkPermission('some-permission');
if (hasPermission) {
// 执行操作
} else {
// 提示无权限
}
}
}
};