设计思路
- 定义权限验证装饰器:使用TypeScript装饰器语法,定义用于方法或类的权限验证装饰器。通过装饰器参数传递所需的权限信息。
- 权限规则存储与管理:创建一个模块来集中管理权限规则,比如可以用一个对象或数据库来存储角色与权限的对应关系、数据范围权限等。
- 上下文获取:在权限验证过程中,需要获取当前用户的角色、数据范围等上下文信息。可以通过全局状态管理(如Redux等)或者在请求上下文中传递。
- 可扩展性:设计的框架应易于添加新的权限验证逻辑,例如新的角色继承规则或数据范围验证方式,通过模块化设计和接口抽象来实现。
关键代码示例
- 定义权限验证装饰器
// 权限验证装饰器
function checkPermissions(requiredPermissions: string[]) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
// 这里模拟获取当前用户的权限
const currentUserPermissions = getCurrentUserPermissions();
const hasPermissions = requiredPermissions.every(permission => currentUserPermissions.includes(permission));
if (hasPermissions) {
return originalMethod.apply(this, args);
} else {
throw new Error('没有足够的权限');
}
};
return descriptor;
};
}
// 模拟获取当前用户权限的函数
function getCurrentUserPermissions(): string[] {
// 实际应用中从上下文或全局状态获取
return ['read:data', 'write:data'];
}
- 使用装饰器
class DataService {
@checkPermissions(['read:data'])
readData() {
console.log('读取数据');
}
@checkPermissions(['write:data'])
writeData() {
console.log('写入数据');
}
}
const dataService = new DataService();
dataService.readData();
// dataService.writeData(); // 可能会抛出权限不足的错误
- 数据范围权限示例
// 数据范围权限装饰器
function checkDataScope(dataScope: string) {
return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
const originalMethod = descriptor.value;
descriptor.value = function (...args: any[]) {
// 模拟获取当前用户的数据范围
const currentUserDataScope = getCurrentUserDataScope();
if (currentUserDataScope === dataScope) {
return originalMethod.apply(this, args);
} else {
throw new Error('没有权限访问此数据范围');
}
};
return descriptor;
};
}
// 模拟获取当前用户数据范围的函数
function getCurrentUserDataScope(): string {
// 实际应用中从上下文或全局状态获取
return 'department1';
}
class DepartmentDataService {
@checkDataScope('department1')
accessDepartmentData() {
console.log('访问部门1的数据');
}
}
const departmentDataService = new DepartmentDataService();
departmentDataService.accessDepartmentData();