Nestjs 使用bcrypt来散列用户密码(哈希)
前言
之前使用了crypto-js
做了一个md5加密用户密码的操作,但是由于该库本身没有提供比对方法,于是自己去实现了一个方法,而且还需要自己提供一个唯一值盐。
最近发现bcrypt
这个库更好用,于是改用它了。
安装依赖
pnpm i bcrypt
pnpm i @types/bcrypt -D
教程
原来使用crypto-js
的MD5方法,需要自己提供盐(salt),之前的做法是创建一个环境变量,然后预设一个定死的string字符串,这就导致我们需要维护一份唯一值的盐,有点麻烦。
而bcrypt
自身可以生成盐,并且它的盐会通过某些方式存储在加密后的字符串上,然后比对的时候,我们不需要知道之前它的盐是什么,它自己会从加密后的string中取,然后再去比对,所以非常方便。
.env.development
# hash-saltOrRounds
HASH_SALT_OR_ROUNDS="12"
我们在环境变量文件中创建一个变量,这个变量表示生成的盐的位数,推荐在10-12之间,可以保证一个很好的性能和加密效果,如果位数过多,会导致hash的时候耗时非常长。
然后我们调整之前auth.service.ts
服务
import { BadRequestException, Injectable } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { RegisterDto } from "./dto/register.dto";
import { LoginDto } from "./dto/login.dto";
import { PrismaService } from "src/prisma/prisma.service";
import { JwtService } from "@nestjs/jwt";
import type { User } from "@prisma/client";
import { hash, compare } from "bcrypt";
@Injectable()
export class AuthService {
constructor(
private readonly prisma: PrismaService,
private readonly config: ConfigService,
private readonly jwtService: JwtService
) {}
/** 注册账号 */
async register(data: RegisterDto) {
const { email, password } = data;
const user = await this.prisma.user.create({
data: {
email,
password: await hash(password, Number(this.config.get("HASH_SALT_OR_ROUNDS")))
}
});
return this.generateToken(user);
}
/** 登录 */
async login(data: LoginDto) {
const { email, password } = data;
// 查找用户
const findUser = await this.prisma.user.findFirst({
where: {
email
}
});
// 比对密码
const isMatch = await compare(password, findUser.password);
if (!isMatch) {
throw new BadRequestException("密码错误");
}
return this.generateToken(findUser);
}
/** 生成token */
private async generateToken({ id, email }: User) {
return {
token: await this.jwtService.signAsync({
sub: id,
email: email
})
};
}
}
从bcrypt
引入hash、compare
方法,hash方法第二个参数如果是number类型的值,它会自己去生成指定位数的盐,所以我们从环境变量取到HASH_SALT_OR_ROUNDS
后进行一个Number转换。
compare
传入两个参数,第一个是未加密前的值,第二个是加密后的值,它自己会去比对,原来后之前封装的md5里面的verify
方法差不多。
bcrypt
库同时还提供了同步的方法,后缀是带Sync的,大家可以根据自己需要使用。
版权申明
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿站点。未经许可,禁止转载。
暂无评论数据