Nestjs使用crypto-js对密码实现保护
简介
所有的数据库中,对密码的保存永远不是明文的,这是一种常识,我们使用Nestjs和Prisma创建用户时也是一样的,对用户的密码也不是明文的。
有些教程使用argon2
库来加密密码,但是这个库在windows上永远是安装失败,为此直接放弃使用它,改用crypto-js
,来实现相同功能。
教程
先安装依赖:
pnpm i crypto-js @types/crypto-js
然后我们封装一个简单的工具文件:md5.ts
import { MD5 } from "crypto-js";
/**
* @description: hash加密
* @param {string} val 要加密的字符串
* @param {*} salt 盐
* @Date: 2024-01-02 07:33:26
* @Author: mulingyuer
*/
export function hash(val: string, salt = "") {
return MD5(`${val}${salt}`).toString();
}
/**
* @description: 比对加密后的字符串
* @param {string} val 要比对的字符串
* @param {string} hashVal 加密后的字符串
* @param {*} salt 盐
* @Date: 2024-01-02 07:35:22
* @Author: mulingyuer
*/
export function verify(val: string, hashVal: string, salt = "") {
return hash(val, salt) === hashVal;
}
这里我们使用了salt
盐,它的作用就是增加密码的难度,假设我的密码是123456
,但是我的盐是:u9Uo9ibS9N@9tZ
,将它们进行组合。
123456u9Uo9ibS9N@9tZ
u9Uo9ibS9N@9tZ123456
再将它们转换成MD5值,你会得到一个很难破解的加密值,如果你没有我的盐,那么基本上无法正确解密出密码,通过这种方式我们就可以很安全的存储用户的密码,且不是一个明文的。
当然我们还有很多复杂的加密方式,这取决于你的项目需要的安全程度,但是逻辑上都是相同的。
盐怎么配置
盐可以是一段自己随便输入的字符串,推荐是:英文+数字+符号,越长越复杂,越难破译。
我们可以将其存储在环境变量中,在Nestjs中,我们通过@nestjs/config
加载环境变量,具体可以查看《Nestjs与Prisma多环境变量文件解决方案》这篇文章。
假设我们的环境变量:
.env.development
# md5-salt
MD5_SALT="u9Uo9ibS9N@9tZ"
使用
import { BadRequestException, Injectable } from "@nestjs/common";
import { ConfigService } from "@nestjs/config";
import { LoginDto, RegisterDto } from "src/dto/auth.dto";
import { PrismaService } from "src/prisma/prisma.service";
import { hash, verify } from "../utils/md5";
@Injectable()
export class AuthService {
constructor(
private readonly prisma: PrismaService,
private readonly config: ConfigService
) {}
/** 注册账号 */
async register(data: RegisterDto) {
const { email, password } = data;
const md5Salt: string = this.config.get("MD5_SALT");
const user = await this.prisma.user.create({
data: {
email,
password: hash(password, md5Salt)
}
});
return user;
}
/** 登录 */
async login(data: LoginDto) {
const { email, password } = data;
const md5Salt: string = this.config.get("MD5_SALT");
// 查找用户
const findUser = await this.prisma.user.findFirst({
where: {
email
}
});
// 比对密码
if (!verify(password, findUser.password, md5Salt)) {
throw new BadRequestException("密码错误");
}
return findUser;
}
}
通过this.config.get("MD5_SALT")
我们可以获取到环境变量中的盐,然后使用它。
再通过hash
和verify
方法实现加密和比对。
版权申明
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿站点。未经许可,禁止转载。
暂无评论数据