当前位置: 首页 > article >正文

在使用 TypeORM 的项目中,如果不希望查询返回 password 字段,可以通过以下几种方式实现

在使用 TypeORM 的项目中,如果不希望查询返回 password 字段,可以通过以下几种方式实现:


1. 使用 @Exclude 装饰器(推荐)

通过 class-transformer@Exclude 装饰器隐藏字段,使得返回的对象在序列化时不会包含 password

实现步骤:
  1. 安装 class-transformer

    npm install class-transformer
    
  2. User 实体中添加 @Exclude

    import { Exclude } from 'class-transformer';
    import { Entity, Column, PrimaryGeneratedColumn } from 'typeorm';
    
    @Entity('users')
    export class User {
      @PrimaryGeneratedColumn('uuid')
      id: string;
    
      @Column()
      username: string;
    
      @Exclude() // 使用 Exclude 隐藏 password 字段
      @Column()
      password: string;
    
      @Column()
      email: string;
    }
    
  3. 在返回时应用 class-transformerplainToClass
    在控制器或服务中将查询结果转化为实例对象,并自动排除标记为 @Exclude 的字段。

    import { plainToInstance } from 'class-transformer';
    import { User } from './entities/user.entity';
    
    const users = await this.userRepository.find();
    return plainToInstance(User, users); // 将 User 实体转化为响应对象
    

2. 使用 select 指定查询字段

如果某些查询仅需要部分字段,可以在 TypeORM 查询时通过 select 显式排除 password

示例:
const users = await this.userRepository.find({
  select: ['id', 'username', 'email'], // 仅查询需要的字段
});

3. 使用 @Column({ select: false })

TypeORM 提供了 select: false 属性,使得 password 默认不被查询到,但在需要时仍可以显式加载。

修改实体:
@Entity('users')
export class User {
  @PrimaryGeneratedColumn('uuid')
  id: string;

  @Column()
  username: string;

  @Column({ select: false }) // 默认不查询 password 字段
  password: string;

  @Column()
  email: string;
}
查询时显式加载 password
const user = await this.userRepository.findOne({
  where: { id: userId },
  select: ['id', 'username', 'password'], // 显式加载 password
});

4. 使用 DTO 转换响应对象

通过使用 DTO(数据传输对象)来控制返回的字段,从根本上避免 password 被直接返回。

定义 DTO:
export class UserResponseDto {
  id: string;
  username: string;
  email: string;
}
在服务中转换为 DTO:
import { UserResponseDto } from './dto/user-response.dto';

const users = await this.userRepository.find();
return users.map(user => new UserResponseDto(user));

5. 结合全局拦截器

如果所有接口返回都需要处理,可以创建一个全局拦截器,自动过滤掉敏感字段。

创建拦截器:
import {
  Injectable,
  NestInterceptor,
  ExecutionContext,
  CallHandler,
} from '@nestjs/common';
import { Observable } from 'rxjs';
import { map } from 'rxjs/operators';

@Injectable()
export class ExcludePasswordInterceptor implements NestInterceptor {
  intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
    return next.handle().pipe(
      map(data => {
        if (Array.isArray(data)) {
          return data.map(user => {
            delete user.password;
            return user;
          });
        } else if (data && typeof data === 'object') {
          delete data.password;
          return data;
        }
        return data;
      }),
    );
  }
}
在模块中注册拦截器:
import { Module } from '@nestjs/common';
import { APP_INTERCEPTOR } from '@nestjs/core';
import { ExcludePasswordInterceptor } from './interceptors/exclude-password.interceptor';

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

选用建议

  1. @Exclude + class-transformer

    • 最灵活且易维护,适合大型项目。
  2. @Column({ select: false })

    • 默认查询不包括 password,简单有效。
  3. 结合全局拦截器

    • 如果有大量涉及 password 的字段隐藏需求,全局拦截器是最佳选择。

综合使用这些方法可以确保项目的安全性和代码的可维护性。


http://www.kler.cn/a/402954.html

相关文章:

  • 深入理解索引(一)
  • VMware虚拟机Ubuntu桥接模式突然连接不上网络解决办法
  • 怎么只提取视频中的声音?从视频中提取纯音频技巧
  • 服务器产品
  • python之开发笔记
  • IText创建加盖公章的pdf文件并生成压缩文件
  • 说说数字化的误区
  • MongoDB进阶篇-索引(索引概述、索引的类型、索引相关操作、索引的使用)
  • 数据建模-业务分类、数据域、主题
  • 【Linux课程学习】:对操作系统(Operator System)的理解
  • 李春葆《数据结构》——图相关代码
  • JVM垃圾回收算法详解
  • C语言内存:我家大门常打开
  • 手机ip地址异常怎么解决
  • tcn 对比 cnn-attension-gru联合模型,时间序列预测,深度神经网络
  • C# 数据结构之【链表】C#链表
  • PN、VFC、PNC局部网络管理
  • django西西家居全屋定制系统的设计与实现
  • Conda环境Git Pull报错
  • Nmap识别MongoDB 6.0指纹
  • Node.js windows版本 下载和安装(详细步骤)
  • C++:探索AVL树旋转的奥秘
  • RBTree--红黑树
  • MySQL 架构概览
  • 开源一个练手的项目,就叫新闻助手吧
  • vue中动态渲染静态图片资源