Nestjs 密码以纯文本形式存储在数据库中

Nestjs 密码以纯文本形式存储在数据库中,nestjs,typeorm,password-hash,Nestjs,Typeorm,Password Hash,我在服务器上进行授权和用户注册。在搜索中我找到了一个小向导。随后他进行了注册和用户授权。我的问题是,在注册过程中,密码存储在数据库中 注册后,密码以明文形式存储 控制器和模型与我上面引用的手册中的控制器和模型没有区别 @Post('login') async login(@Body() user: UserEntity): Promise<Object> { return await this.authService.login(user); } @Post('regis

我在服务器上进行授权和用户注册。在搜索中我找到了一个小向导。随后他进行了注册和用户授权。我的问题是,在注册过程中,密码存储在数据库中

注册后,密码以明文形式存储

控制器和模型与我上面引用的手册中的控制器和模型没有区别

@Post('login')
async login(@Body() user: UserEntity): Promise<Object> {
    return await this.authService.login(user);
}

@Post('register')
async register(@Body() user: UserEntity): Promise<Object> {
    return await this.authService.register(user);
}
我为自己重写了用户对象

import { Entity, PrimaryGeneratedColumn, Column, BeforeInsert } from 'typeorm';
import { hash, compare } from 'bcryptjs';

@Entity('users')
export class UserEntity {
    @PrimaryGeneratedColumn() id: number;

    @Column({ type: 'varchar', nullable: false }) firstName: string;

    @Column({ type: 'varchar', nullable: false }) lastName: string;

    @Column({ type: 'varchar', nullable: false }) email: string;

    @Column({ type: 'varchar', nullable: false }) password: string;

    @BeforeInsert()
    async hashPassword(): Promise<void> {
        this.password = await hash(this.password, 10);
    }

    async comparePassword(attempt: string): Promise<boolean> {
        return await compare(attempt, this.password);
    }
}
public async login(user: UserEntity) {
    const userData = await this.userService.findByEmail(user.email);
    const result = user.comparePassword(user.password);
    if (!result) {
        return {
            message: 'Password or email is incorrect',
            status: 404,
        };
    }
    return this.getInfo(userData);
}

public async register(user: UserEntity): Promise<Object> {
    const userData = await this.userService.findByEmail(user.email);
    if (userData) {
       return {
            message: 'A user with this email already exists.',
            status: 404,
        };
    }
    const newUser = await this.userService.create(user);
    return this.getInfo(newUser);
}

private async getInfo(userData: UserEntity) {
    const accessToken = this.getAccessToken(userData);
    return {
        accessToken,
        userId: userData.id,
        status: 200,
    };
}

private getAccessToken(userData: UserEntity) {
    return this.jwtService.sign({
        userId: userData.id,
        firstName: userData.firstName,
        lastName: userData.lastName,
        email: userData.email,
    });
}
import{Entity,PrimaryGeneratedColumn,Column,BeforeInsert}来自'typeorm';
从'bcryptjs'导入{hash,compare};
@实体(“用户”)
导出类用户实体{
@PrimaryGeneratedColumn()id:number;
@列({type:'varchar',null:false})firstName:string;
@列({type:'varchar',null:false})lastName:string;
@列({type:'varchar',null:false})email:string;
@列({type:'varchar',nullable:false})密码:string;
@插入()之前
异步hashPassword():承诺{
this.password=等待散列(this.password,10);
}
异步比较密码(尝试:字符串):承诺{
返回等待比较(尝试,此密码);
}
}
我还为自己重写了授权服务

import { Entity, PrimaryGeneratedColumn, Column, BeforeInsert } from 'typeorm';
import { hash, compare } from 'bcryptjs';

@Entity('users')
export class UserEntity {
    @PrimaryGeneratedColumn() id: number;

    @Column({ type: 'varchar', nullable: false }) firstName: string;

    @Column({ type: 'varchar', nullable: false }) lastName: string;

    @Column({ type: 'varchar', nullable: false }) email: string;

    @Column({ type: 'varchar', nullable: false }) password: string;

    @BeforeInsert()
    async hashPassword(): Promise<void> {
        this.password = await hash(this.password, 10);
    }

    async comparePassword(attempt: string): Promise<boolean> {
        return await compare(attempt, this.password);
    }
}
public async login(user: UserEntity) {
    const userData = await this.userService.findByEmail(user.email);
    const result = user.comparePassword(user.password);
    if (!result) {
        return {
            message: 'Password or email is incorrect',
            status: 404,
        };
    }
    return this.getInfo(userData);
}

public async register(user: UserEntity): Promise<Object> {
    const userData = await this.userService.findByEmail(user.email);
    if (userData) {
       return {
            message: 'A user with this email already exists.',
            status: 404,
        };
    }
    const newUser = await this.userService.create(user);
    return this.getInfo(newUser);
}

private async getInfo(userData: UserEntity) {
    const accessToken = this.getAccessToken(userData);
    return {
        accessToken,
        userId: userData.id,
        status: 200,
    };
}

private getAccessToken(userData: UserEntity) {
    return this.jwtService.sign({
        userId: userData.id,
        firstName: userData.firstName,
        lastName: userData.lastName,
        email: userData.email,
    });
}
public异步登录(用户:UserEntity){
const userData=wait this.userService.findByEmail(user.email);
const result=user.comparePassword(user.password);
如果(!结果){
返回{
消息:“密码或电子邮件不正确”,
现状:404,
};
}
返回此.getInfo(userData);
}
公共异步寄存器(用户:UserEntity):承诺{
const userData=wait this.userService.findByEmail(user.email);
如果(用户数据){
返回{
消息:“具有此电子邮件的用户已存在。”,
现状:404,
};
}
const newUser=wait this.userService.create(user);
返回此.getInfo(newUser);
}
私有异步getInfo(userData:UserEntity){
const accessToken=this.getAccessToken(userData);
返回{
accessToken,
userId:userData.id,
现状:200,
};
}
私有getAccessToken(userData:UserEntity){
返回此.jwtService.sign({
userId:userData.id,
firstName:userData.firstName,
lastName:userData.lastName,
电子邮件:userData.email,
});
}
用户服务也保持不变

async findByEmail(email: string): Promise<UserEntity> {
    return await this.userRepository.findOne({ where: { email } });
}

async findById(id: number): Promise<UserEntity> {
    return await this.userRepository.findOne({ where: { id } });
}

async create(user: UserEntity): Promise<UserEntity> {
    return await this.userRepository.save(user);
}
async findByEmail(email:string):承诺{
return wait this.userRepository.findOne({where:{email}});
}
异步findById(id:number):承诺{
return wait this.userRepository.findOne({where:{id}});
}
异步创建(用户:UserEntity):承诺{
返回wait this.userRepository.save(user);
}
我在哪里会出错?现在为什么密码以明文形式存储?在写入数据库之前,我几乎完成了文档和功能,但我知道它不起作用。

在ForeInsert是实例级方法之前,您需要用户的实际实例才能调用它(如果没有this,则无法引用this.password)

您可以尝试这样做(如果您不想在db中存储纯密码):

异步创建(用户:UserEntity):承诺{ user.password=等待散列(user.password,10); 返回wait this.userRepository.save(user); }
我想这是因为您的
@beforeinstert()
函数是异步的。也许您可以尝试使用
hashSync
@fyelci使该函数同步。我也尝试过,但没有帮助。我按照另一个指示行事,这样的问题没有发生在我身上。上述说明的作者在某个地方弄错了,但我找不到他是谁。