如何只为当前用户公开字段?
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] })
此致
仅当登录用户与实体具有相同 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] })
此致