NestJS-bcrypt加密解密使用

举报
林太白 发表于 2025/05/16 13:31:01 2025/05/16
【摘要】 NestJS-bcrypt加密解密使用

NestJS-bcrypt加密解密使用

1、认识安装

在 NestJS 中使用 bcrypt 来进行密码哈希和验证是非常常见的需求。bcrypt 是一个安全的哈希算法,它可以用于加密用户密码,并且提供了验证密码是否匹配的功能。

👉安装 bcrypt

首先,你需要安装 bcrypt 库。使用以下命令进行安装:

npm install bcrypt

// 这里我使用的版本是 "bcrypt": "^5.1.1",

如果你使用的是 TypeScript,bcrypt 可能还需要安装类型定义文件,这里我的

npm install @types/bcrypt --save-dev
//yarn方式安装
yarn add @types/bcrypt --save-dev

// 版本
"@types/bcrypt": "^5.0.2",

2、使用 bcrypt

👉作用

没有经过加密之前我们的密码是这样的

1111111111

加密以后我们的密码

$10$D1L8Dh3L1NKTUaJsvr.7r./dm6p19ix7e7ZwctuMZ1KzdTbEk1muO

之前我们的密码都是明文存储的,接下来我们就加密解密对于密码进行验证

user.password = registerDto.password; 

👉注册迁移到auth模块

之前我们注册模块在user模块之中,接下来我们迁移到auth授权模块

auth.controller.ts
import { RegisterDto } from '@/utils/response.dto';
@Post('register')
  register(@Body() registerDto: RegisterDto) {
    return this.authService.register(registerDto);
  }
auth.module.ts引入用户实体
import { TypeOrmModule } from '@nestjs/typeorm';
import { User } from '@/modules/user/user.entity';

@Module({
  imports: [
    TypeOrmModule.forFeature([User]),  // 注册 User 实体
  ],
  providers: [AuthService, JwtStrategy],
  controllers: [AuthController],
})
export class AuthModule {}

auth.service.ts
import { InjectRepository } from '@nestjs/typeorm';
import { RegisterDto } from '@/utils/response.dto';
import { User } from '@/modules/user/user.entity';
// 异步注册方法
  async register(registerDto: RegisterDto) {
    // 查询数据库中是否存在同名用户
    const existingUser = await this.userRepository.findOne({ where: { username: registerDto.username } });

    // 如果存在同名用户,则抛出异常
    if (existingUser) {
      versionhello('用户注册提示', '用户已存在!');
      // throw new ConflictException('用户已存在!');
      // return {
      //   data: [],
      //   message: '用户已存在!',
      //   code: 400,
      // };
      throw new HttpException(
        {
          code: 400,  // 适当的错误码是 400
          message: '用户已存在!',
        },
        HttpStatus.BAD_REQUEST,  // 使用 400 状态码
      );
    }
    // 创建新用户
    const user = new User();
    user.username = registerDto.username;
    user.password = registerDto.password;
    // user.password = hashedPassword;
    const savedUser = await this.userRepository.save(user); // 保存到数据库
    console.log(savedUser, 'savedUser');
    // 返回注册成功的信息
    return {
      message: '恭喜你,您的账号注册成功!',
      code: 200,
    };
  }

3、加密解密

👉加密

正确引入迁移以后,接下来就可以针对密码进行加密和解密了

加密

//导入
import * as bcrypt from 'bcrypt';
async hashPassword(password: string): Promise<string> {
  const salt = await bcrypt.genSalt(10);  // 生成 salt
  const hashedPassword = await bcrypt.hash(password, salt);  // 用 salt 加密密码
  return hashedPassword;
}

// 加密密码
const hashedPassword = await this.hashPassword(registerDto.password);

//直接使用
user.password = hashedPassword;

加密以后得密码

$2b$10$D1L8Dh3L1NKTUaJsvr.7r./dm6p19ix7e7ZwctuMZ1KzdTbEk1muO

👉解密

加密完以后这个时候我们的密码已经入库,接下来在解密部分反翻译出密码对比,这部分在登录这里实现

 // 验证密码
 async validatePassword(password: string, hashedPassword: string): Promise<boolean> {
    const isMatch = await bcrypt.compare(password, hashedPassword);  // 比较密码
    return isMatch;
  }
完善auth.service.ts
//对比密码

const isPasswordValid = await 
  this.validatePassword(LoginDto.password, loginUser.password);

//简单对比一下用户的账号密码信息
 if(isPasswordValid){
    return {
      message: '登录成功!',
      code: 200,
      token: token,
    };
  }else{
    return {
      message: '用户名或密码错误!',
      code: 400,
    };
  }

4、完整示例

整个过程

注册时加密密码:注册时,使用 bcrypt.hash() 加密密码,与盐值一起生成哈希密码。
登录时验证密码:登录时,使用 bcrypt.compare() 方法比较输入的密码和数据库中存储的哈希密码。
盐值的轮数:bcrypt.genSalt() 方法的 saltRounds 参数控制了生成盐值的复杂度
  常见的值是 10,如果需要更强的加密,可以增加该值。

完整的用户注册时使用 bcrypt 对用户密码进行加密

在服务层(如 AuthService)中处理密码的加密和验证

👉示例

AuthService 中使用 bcrypt

auth.service.ts (加密和验证密码)

typescriptCopy Codeimport { Injectable } from '@nestjs/common';
import * as bcrypt from 'bcrypt';
import { RegisterDto } from './dto/register.dto';

@Injectable()
export class AuthService {
  private readonly saltRounds = 10; // 加密的盐值轮数,通常设为10或更高

  // 加密密码
  async hashPassword(password: string): Promise<string> {
    const salt = await bcrypt.genSalt(this.saltRounds); // 生成盐值
    return await bcrypt.hash(password, salt);  // 生成加密密码
  }

  // 验证密码
  async validatePassword(password: string, hashedPassword: string): Promise<boolean> {
    return await bcrypt.compare(password, hashedPassword);  // 比较原密码和哈希密码
  }

  // 用户注册的逻辑
  async register(registerDto: RegisterDto): Promise<string> {
    const { password } = registerDto;
    const hashedPassword = await this.hashPassword(password);  // 将密码加密
    // 假设保存用户数据到数据库,通常会在这里调用 Repository 或 ORM 方法保存
    console.log('Hashed Password:', hashedPassword);
    return 'User registered successfully';
  }
}

register.dto.ts

typescriptCopy Codeimport { IsString, IsEmail, IsNotEmpty, MinLength } from 'class-validator';

export class RegisterDto {
  @IsString()
  @IsNotEmpty()
  @MinLength(3)
  username: string;

  @IsEmail()
  @IsNotEmpty()
  email: string;

  @IsString()
  @IsNotEmpty()
  @MinLength(6)
  password: string;
}

auth.controller.ts (使用 AuthService)

typescriptCopy Codeimport { Body, Controller, Post } from '@nestjs/common';
import { AuthService } from './auth.service';
import { RegisterDto } from './dto/register.dto';

@Controller('auth')
export class AuthController {
  constructor(private readonly authService: AuthService) {}

  @Post('register')
  async register(@Body() registerDto: RegisterDto) {
    return await this.authService.register(registerDto);  // 调用 AuthService 中的 register 方法
  }
}
  1. 使用 bcrypt 验证密码

在用户登录时,你会需要将用户输入的密码与数据库中存储的哈希密码进行比较。这是通过 bcrypt.compare() 方法来实现的,它会对输入的密码进行哈希并与存储的哈希进行比较。

在上面的 AuthService 中,已经提供了一个 validatePassword 方法来验证密码是否正确。这个方法使用 bcrypt.compare() 来比较输入密码和哈希密码。

AuthService 中验证密码

typescriptCopy Code// 在 AuthService 中验证密码
async login(loginDto: LoginDto): Promise<string> {
  const { email, password } = loginDto;

  // 假设从数据库中获取用户的哈希密码
  const user = await this.userRepository.findOne({ where: { email } });
  if (!user) {
    throw new Error('User not found');
  }

  // 使用 bcrypt 比较密码
  const isPasswordValid = await this.validatePassword(password, user.password);
  if (!isPasswordValid) {
    throw new Error('Invalid credentials');
  }

  return 'Login successful';
}

通过以上方法,NestJS 中就能安全地加密和验证用户的密码了。

【声明】本内容来自华为云开发者社区博主,不代表华为云及华为云开发者社区的观点和立场。转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息,否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。