【问题标题】:How do you detect if an attribute like password has changed in typeorm如何检测 typeorm 中的密码等属性是否已更改
【发布时间】:2019-01-12 19:49:36
【问题描述】:

在 typeorm 中,我尝试使用订阅者装饰器在持久化到数据库之前对用户密码进行哈希处理。不幸的是,我在文档中找不到参考。

在sequelizejs中,我使用如下代码,

User.hashPassword = (user, options) => {
    if (!user.changed('password')) {
      return null;
    }
    // hash password
    return Bcrypt.hash(user.get('password'), SALT_ROUNDS)
      .then(hash => user.set('password', hash));
  };

现在,我正在尝试将代码迁移到typeorm,我的翻译大致是

@BeforeInsert()
@BeforeUpdate()
hashPassword() {
    // conditional to detect if password has changed goes here
    this.password = bcrypt.hashSync(this.password, SALT_ROUNDS);
}

问题是,我停留在!user.changed('password')typeorm 中是否有等效功能可以在不推出我自己的解决方案的情况下执行此操作?

【问题讨论】:

  • 你找到解决办法了吗?
  • @Hammerbot 不,我没有。我所做的是检查更新请求中是否存在 user.password 属性。如果存在,请确认它是纯字符串以防止双重哈希。然后在持久化之前在纯字符串上手动运行bcrypt.hash()
  • 您是否尝试过使用订阅者? github.com/typeorm/typeorm/blob/master/docs/…

标签: javascript node.js nestjs typeorm


【解决方案1】:

在@adetoola 自己的issue 中找到了这个问题的解决方案。 可以使用@AfterLoad加载用户密码,查看当前密码是否不同:

@Entity()
export class User extends BaseEntity {
    @PrimaryColumn()
    public username: string;

    @Column()
    public password: string;

    @Column({ nullable: true })
    public jwtToken: string;

    private tempPassword: string;


    @AfterLoad()
    private loadTempPassword(): void {
        this.tempPassword = this.password;
    }

    @BeforeUpdate()
    private encryptPassword(): void {
        if (this.tempPassword !== this.password) {
            //
        }
    }

【讨论】:

  • 这里需要注意的是,在使用 .update().delete() 等存储库方法时,不会触发实体侦听器,因为没有加载实体。如果您想确保这些方法触发,您需要加载实体(使用.findOne()),更新它,然后使用.save() 方法。更多详情请见this github thread
【解决方案2】:

你可以试试这个:

@BeforeInsert()
@BeforeUpdate()
hashPassword() {
  if (this.password) {
    this.password = createHmac('sha256', this.password).digest('hex');
  }
}

我只是检查 DTO 中是否存在密码(在更新和插入之前)。如果存在,我应该对其进行哈希处理。

【讨论】:

    【解决方案3】:
    ----------
    
        private tempPassword: string
    
      /// commit to handle the password if i not change it it will be  not encription
    
    
      @AfterLoad()
      private loadTempPassword(): void {
        this.tempPassword = this.password;
      }
    
    
    
    
      @BeforeInsert()
      @BeforeUpdate()
      async hashPassword(): Promise<void> {
        // cheack if that password changing or not
        if (this.tempPassword !== this.password) {
    
          try {
            this.password = await bcrypt.hash(this.password, 10)
    
          } catch (e) {
            throw new InternalServerErrorException('there are some issiue in the hash')
    
          }
        }
    
    
      }
    

    【讨论】:

      【解决方案4】:

      我们可以从列中选择密码

       @Column('string', { select: false })
         password:string
      

      然后我们尝试散列

      we check if the password is found or not 
       if (this.password) {
      //make hash 
      }
      

      或其他方式 它应该使 private tempPassword: string

         @AfterLoad()
        private loadTempPassword(): void {
          this.tempPassword = this.password;
        }
      

      @BeforeInsert()
        @BeforeUpdate()
        async hashPassword(): Promise<void> {
          // cheack if that password changing or not
          if (this.password) {
            if (this.tempPassword !== this.password) {
      
              try {
                this.password = await bcrypt.hash(this.password, 10)
      
              } catch (e) {
                throw new InternalServerErrorException('there are some issiue in the hash')
      
              }
            }
          }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-08-18
        • 2013-06-14
        • 2019-05-29
        • 2020-12-22
        • 2015-01-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多