MST

星途 面试题库

面试题:TypeScript装饰器中Reflect Metadata的复杂应用

假设你正在开发一个基于TypeScript的Web应用,需要对某些类的方法进行权限控制。请使用装饰器和Reflect Metadata实现一个权限验证的机制,要求能够根据不同的用户角色来决定是否允许访问被装饰的方法。
24.5万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试
  1. 定义权限装饰器
    • 首先,我们需要定义一个装饰器,它接受一个表示权限的字符串数组作为参数。这个装饰器将使用Reflect Metadata来存储权限信息。
    import 'reflect - metadata';
    
    const PERMISSION_KEY = 'permissions';
    
    function checkPermissions(permissions: string[]) {
        return function (target: any, propertyKey: string, descriptor: PropertyDescriptor) {
            Reflect.defineMetadata(PERMISSION_KEY, permissions, target, propertyKey);
            return descriptor;
        };
    }
    
  2. 定义用户角色和权限验证函数
    • 假设我们有一个User类来表示用户,包含用户角色信息。
    • 然后定义一个函数来验证用户是否具有访问某个方法的权限。
    class User {
        constructor(public role: string) {}
    }
    
    function hasPermission(user: User, target: any, propertyKey: string) {
        const requiredPermissions = Reflect.getMetadata(PERMISSION_KEY, target, propertyKey);
        if (!requiredPermissions) {
            return true;
        }
        // 这里简单假设角色和权限有对应关系,实际应用中可能更复杂
        if (user.role === 'admin') {
            return true;
        }
        for (const permission of requiredPermissions) {
            if (user.role === permission) {
                return true;
            }
        }
        return false;
    }
    
  3. 使用装饰器和验证机制
    • 我们定义一个示例类,其中的方法使用权限装饰器。
    • 然后在调用方法前,通过hasPermission函数进行权限验证。
    class ExampleClass {
        @checkPermissions(['admin', 'editor'])
        editContent() {
            console.log('编辑内容');
        }
    
        @checkPermissions(['admin'])
        deleteContent() {
            console.log('删除内容');
        }
    }
    
    const user = new User('editor');
    const example = new ExampleClass();
    
    const propertyKey1 = 'editContent';
    if (hasPermission(user, example, propertyKey1)) {
        example[propertyKey1]();
    } else {
        console.log('无权限访问该方法');
    }
    
    const propertyKey2 = 'deleteContent';
    if (hasPermission(user, example, propertyKey2)) {
        example[propertyKey2]();
    } else {
        console.log('无权限访问该方法');
    }
    

以上代码展示了如何使用装饰器和Reflect Metadata在TypeScript中实现基于用户角色的权限验证机制。

  1. 装饰器部分checkPermissions装饰器接受权限数组,并使用Reflect.defineMetadata将权限信息存储在目标方法上。
  2. 验证部分hasPermission函数从目标方法上获取所需权限,并根据用户角色判断用户是否具有访问权限。
  3. 使用部分ExampleClass中的方法使用checkPermissions装饰器,在调用方法前通过hasPermission函数进行权限验证。