2025.3.23 일요일의 공부기록
bcrypt는 비밀번호와 같은 민감한 정보를 안전하게 저장하기 위해 사용하는 대표적인 해시(Hash) 함수이다.
해시 함수는 입력값을 고정된 길이의 난수 형태로 변환하며, 단방향(One-way) 및 멱등성(idempotent)을 갖는다.
해시 함수의 특성
bcrypt를 사용하는 이유는 다음과 같다.
다음 명령어로 프로젝트에 bcrypt를 설치한다.
npm i bcrypt
npm i @types/bcrypt
@types/bcrypt
를 설치해야 한다.bcrypt는 비동기적으로 작동하는 라이브러리로, 내부적으로는 Promise 객체를 반환한다.
async/await를 사용하는 이유는 bcrypt가 비동기 연산을 기반으로 하므로, 코드가 간결해지고 Promise를 더 쉽게 관리할 수 있기 때문이다.
다음은 Zod를 이용하여 데이터를 검증한 후, bcrypt로 비밀번호를 해시하여 데이터베이스에 저장하는 실습 예시이다.
import bcrypt from 'bcrypt';
import { z } from 'zod';
import db from './lib/db'; // Prisma Client import 예시
// 사용자 입력 데이터 스키마 정의 (Zod)
const formSchema = z.object({
username: z.string().min(3).max(20),
email: z.string().email(),
password: z.string().min(6),
});
// 비밀번호 해시 및 데이터베이스 저장
async function registerUser(data: any) {
const result = await formSchema.safeParseAsync(data);
if (!result.success) {
// 데이터 검증 실패 시, 에러 반환
return result.error.flatten();
} else {
// 데이터 검증 성공 시 비밀번호 해시
const hashedPassword = await bcrypt.hash(result.data.password, 12);
/*
bcrypt.hash(비밀번호, saltRounds)
- saltRounds 값이 높을수록 보안성이 좋아지지만, 처리 속도는 느려진다.
- 권장 값은 10~12이다.
*/
// Prisma를 사용하여 데이터베이스에 사용자 저장
const user = await db.user.create({
data: {
username: result.data.username,
email: result.data.email,
password: hashedPassword, // 해시된 비밀번호 저장
},
select: {
id: true, // 생성된 사용자 ID만 반환
},
});
console.log(user);
// To-do : 로그인 처리 또는 홈 페이지로 리다이렉트 처리 가능
}
}
hash
메서드)const hashedPassword = await bcrypt.hash(비밀번호, saltRounds);
saltRounds
의 권장값은 보통 10~12
이며, 높을수록 보안성이 강화된다.compare
메서드)저장된 해시값과 입력된 비밀번호를 비교할 때 사용한다.
const isCorrect = await bcrypt.compare(입력된비밀번호, 저장된해시값);
if (isCorrect) {
// 비밀번호가 일치함
} else {
// 비밀번호가 일치하지 않음
}