NestJS 강의에서 비크립트를 사용했었다. 사용한 경험이 있었기 때문에 어렵지 않았는데 내가 사용한 방법과 달라서 찾아보던 중에 갑자기 예전에 그냥 아 이런거구나 하고 넘어갔던 콜백헬을 파고들게 되었다.
콜백함수 사용
const bcrypt = require('bcrypt');
// 솔트의 라운드 수를 정합니다. 라운드 수가 높을수록 보안이 강화되지만 처리 시간이 늘어납니다.
const saltRounds = 10;
// 사용자로부터 받은 비밀번호
const myPlaintextPassword = 'my_password';
// 솔트를 생성하고 비밀번호를 해시화합니다.
bcrypt.genSalt(saltRounds, function(err, salt) {
if (err) throw err;
// 비밀번호 해시화
bcrypt.hash(myPlaintextPassword, salt, function(err, hash) {
if (err) throw err;
// 해시화된 비밀번호를 출력하거나 데이터베이스에 저장합니다.
console.log(hash);
});
});
bcrypt.genSalt에 콜백이 있고 그 콜백 안에 다시 bcrypt.hash가 있고 다시 또 콜백으로 암호화가 된다.
bcrypt.genSalt -> 콜백1 -> bcrypt.hash -> 콜백2
전체 과정
- bcrypt.genSalt(saltRounds, callback) 함수를 호출합니다.
- 이 함수는 saltRounds 값을 기반으로 솔트를 생성합니다.
- 생성된 솔트는 콜백 함수의 두 번째 인자로 전달됩니다.
- 콜백 함수 내에서, 이 salt 값을 사용하여 bcrypt.hash() 함수를 호출하고, 평문 비밀번호를 해시화하려고 시도합니다.
- bcrypt.hash() 함수는 전달된 평문 비밀번호와 솔트 값을 결합합니다.
- 결합된 값에 대해 bcrypt는 내부적으로 해시 알고리즘을 실행하여 안전한 해시 값을 생성합니다.
- 생성된 해시 값은 bcrypt.hash() 함수의 콜백의 두 번째 인자로 전달됩니다.
- 콜백 함수 내에서, 이 hash 값을 사용하여 원하는 작업 (예: 콘솔에 출력, 데이터베이스에 저장 등)을 수행할 수 있습니다.
async/await을 사용한 경우
const bcrypt = require('bcrypt');
const saltRounds = 10;
const myPlaintextPassword = 'my_password';
async function hashPassword(plaintextPassword) {
try {
const salt = await bcrypt.genSalt(saltRounds);
const hash = await bcrypt.hash(plaintextPassword, salt);
console.log(hash);
return hash;
} catch (err) {
console.error(err);
throw err;
}
}
hashPassword(myPlaintextPassword); // 함수를 호출해야 실제로 실행됩니다.
콜백이 아닌 await를 통해서 처리하는데 흐름을 보기가 쉽다. 이걸 보고 콜백헬이라고 하는 구나 좀 더 명확하게 알 수 있었다.
- 기존 콜백 패턴:
- 코드를 실행하면 bcrypt.genSalt 함수가 바로 실행되고, 그 함수의 결과에 따라 콜백 함수가 실행됩니다. 이 콜백 함수 내에서는 bcrypt.hash가 실행되며, 그 결과에 따라 또 다른 콜백 함수가 실행됩니다.
- 리팩토링된 비동기 패턴:
- async로 선언된 hashPassword 함수를 먼저 정의만 합니다. 이 함수 내에서는 await를 사용하여 bcrypt.genSalt와 bcrypt.hash의 완료를 순차적으로 기다리고 실행합니다. 하지만, 이 함수는 정의만 되어 있고 아직 실행되지 않았습니다.
- 따로 함수 호출 hashPassword(myPlaintextPassword);를 사용하여 hashPassword 함수를 실행하게 됩니다. 이 함수 호출을 하지 않으면 hashPassword 내부의 코드는 실행되지 않습니다.
'오늘 뭐했냐 > 개발에 대한 주저리' 카테고리의 다른 글
23.10.07 ORM을 사용하면서 쿼리가 복잡해지는 경우 (0) | 2023.10.12 |
---|---|
23.10.06 REST API (0) | 2023.10.11 |
23.10.04 프레임워크 라이브러리 (0) | 2023.10.10 |
23.10.03 도메인 주도 설계 (Domain-driven design, DDD) (0) | 2023.10.05 |
23.10.02 NestJS에서 모듈(Module) (0) | 2023.10.04 |