2

让我们简化 TypeORM 实体User

@Entity()
export class User extends BaseDatabaseEntity {
  @Column({
    length: 255,
  })
  public firstName!: string;

  @Column({ length: 60 })
  @Exclude()
  public password: string;

  @BeforeUpdate()
  @BeforeInsert()
  private hashPassword(): void {
    const tmpPassword = hashSync(
      this.password + 'config.auth.password.secret',
      genSaltSync(),
    );
    this.password = tmpPassword;
  }
}

}

我需要config.auth.password.secret用 NestJS 的配置(来自 ConfigService 的命名空间)替换:

export default registerAs('app', () => {
   return {
    password: {
      secret: process.env.AUTH_PASSWORD_SECRET,
    }
  };
});

,但实体不是 NestJS 结构的一部分,所以我不能像往常一样注入它。

如何在 TypeORM 实体中实现 NestJS 配置?

4

3 回答 3

1

实体不是 NestJS 中可注入提供程序的一部分,因此本质上这是不可能的。但是,您可以将其作为服务代码的一部分,并在插入/更新之前在那里进行密码散列。

于 2020-02-18T18:45:46.777 回答
1

我也需要这个并想出了解决方法。如前所述,您不能将配置注入实体。

我想出了使用实体中需要的配置值导出对象的解决方案:

在应用模块中初始化配置:

  imports: [
    ConfigModule.forRoot({
      isGlobal: true,
      load: [defaultConfig]
    }),
// .....other imports
  ]

defaultConfig是一个收集和检查配置值的函数。最重要的是,它将值设置为STATIC_CONFIG对象。

export const STATIC_CONFIG = {
  WEB_APP_URL: '',
  BASE_URL: '',
};

export const defaultConfig = () => {
  const port = +(process.env[ENV_SERVER.PORT] || 3000);
  const production = process.env.NODE_ENV === 'production';
  const retVal = {
    PRODUCTION: production,
    PORT: port,
    BASE_URL: process.env.BASE_URL || 'http://localhost:3000',
    URL_PREFIX: process.env.URL_PREFIX || 'http://localhost:3000',
//    ..... plenty of other values
  }

  if (retVal[ENV_S3.HOST] && !(retVal[ENV_S3.ACCESS] && retVal[ENV_S3.SECRET])) {
    // tslint:disable-next-line:no-console
    console.error('S3 configuration error: no access or secret set; exiting');
    process.exit(1);
  }

  STATIC_CONFIG.WEB_APP_URL = retVal.WEB_APP_URL;
  STATIC_CONFIG.BASE_URL = retVal.BASE_URL;

  return retVal;
};

最后,在我的实体中,我使用了该STATIC_CONFIG对象,例如:

  @Expose({ name: 'image', toPlainOnly: true, groups: [TG_MOBILE] })
  get mobileAppImage() {
    return this.id ? `${STATIC_CONFIG.BASE_URL}/static/image/${this.id}` : undefined;
  }
于 2020-07-14T07:08:46.873 回答
0
@Entity()
export class User extends BaseDatabaseEntity {
  @Column({
    length: 255,
  })
  public firstName!: string;

  @Column({
    length: 60,
    transformer: new PasswordTransformer(new ConfigService())
  })
  @Exclude()
  public password: string;
}
export class PasswordTransformer implements ValueTransformer {
  constructor(private config: ConfigService) {}

  from(value: string): string {
    return value;
  }

  to(value: string): string {
    return hashSync(
      this.password + this.config.get('AUTH_PASSWORD_SECRET'),
      genSaltSync(),
    );
  }
}

于 2021-08-31T10:42:31.743 回答