如何只为当前用户公开字段?

How to Expose field for the current user only?

仅当登录用户与实体具有相同 ID 时,我才会序列化实体用户的 属性 'email'。

实体用户:

@Entity()
@Exclude()
export class User {

    @Expose()
    @PrimaryGeneratedColumn("uuid")
    id: string;

    @Expose() // Only if logged user == this
    @Column({nullable: true, default: null})
    public email: string;

    @Expose()
    @Column({nullable: true, default: null})
    public username: string;

    @Column({nullable: true, default: null})
    public password: string;

    @CreateDateColumn()
    public create_at: Date;

    @UpdateDateColumn()
    public update_at: Date;
}

你可以这样做:

@Entity()
@Exclude()
export class User {

    @Expose()
    @PrimaryGeneratedColumn("uuid")
    id: string;

    @Column({nullable: true, default: null})
    public email: string;

    public connectedUser: string?;

    @Expose({ name: 'email'}) // Only if logged user
    public get hideableEmail(): string? {
        if(this.email === this.connectedUser) {
            retun this.email;
        }
        return null;
    }

    @Expose()
    @Column({nullable: true, default: null})
    public username: string;

    @Column({nullable: true, default: null})
    public password: string;

    @CreateDateColumn()
    public create_at: Date;

    @UpdateDateColumn()
    public update_at: Date;
}

没有直接的方法可以根据对象本身有条件地排除属性。您可以使用组来控制曝光:

@Expose({ groups: ['owner'] })
@Column({nullable: true, default: null})
public email: string;

然后在您的控制器中根据您的条件添加组:

const groups = [];
if (isCurrentUser) {
  groups.push('owner');
}
classToPlain(user, { groups })

因为我花了两天时间才找到最优雅的解决方案,所以我将其保留在这里以供将来参考并节省人们的时间。 创建一个扩展 ClassSerializerInterceptor 的拦截器。 N.B。 = 您需要让用户在其角色的上下文中注册

import { CallHandler, ClassSerializerInterceptor, ExecutionContext, Injectable } from "@nestjs/common";
import { Observable } from "rxjs";

@Injectable()
export class TransformWithGroupsInterceptor extends ClassSerializerInterceptor {

intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    const { user } = context.switchToHttp().getRequest();
    Reflect.defineMetadata('class_serializer:options', { 'groups': user.roles }, context.getHandler());
    return super.intercept(context, next);
  };
};

然后全局分配拦截器

import { Module } from '@nestjs/common';
import { APP_INTERCEPTOR } from '@nestjs/core';

@Module({
providers: [
  {
    provide: APP_INTERCEPTOR,
    useClass: LoggingInterceptor,
  }
]})
export class AppModule {}

现在您可以使用例如

@Expose({ groups: [Role.Admin] })

此致