๊ด€๋ฆฌ ๋ฉ”๋‰ด

<Hello Hosung๐Ÿ˜Ž/>

[Node.js] bcrypt ๋กœ ํšŒ์›๊ฐ€์ž… ๊ตฌํ˜„ํ•˜๊ธฐ ๋ณธ๋ฌธ

๐Ÿ“ฑ JavaScript/ใ…คNode

[Node.js] bcrypt ๋กœ ํšŒ์›๊ฐ€์ž… ๊ตฌํ˜„ํ•˜๊ธฐ

์ขŒ์ถฉ์šฐ๋Œ ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์ž ์ผ๊ธฐ๐Ÿง 2024. 10. 15. 11:20

 

 

ํšŒ์›๊ฐ€์ž… ์‹œ ์‚ฌ์šฉ์ž๋กœ๋ถ€ํ„ฐ ์ˆ˜์ง‘ํ•œ ์•„์ด๋””์™€ ๋น„๋ฐ€๋ฒˆํ˜ธ ๊ฐ™์€ ์ •๋ณด๋ฅผ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅํ•˜๊ฒŒ ๋ฉ๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋•Œ ์ฃผ์˜ํ•  ์ ์€ ๋น„๋ฐ€๋ฒˆํ˜ธ์™€ ๊ฐ™์€ ๋ฏผ๊ฐํ•œ ์ •๋ณด๋ฅผ ์•”ํ˜ธํ™”ํ•˜์ง€ ์•Š๊ณ  ํ‰๋ฌธ ๊ทธ๋Œ€๋กœ ์ €์žฅํ•  ๊ฒฝ์šฐ์ž…๋‹ˆ๋‹ค. ๋งŒ์•ฝ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค๊ฐ€ ์œ ์ถœ๋˜๋ฉด, ์•…์˜์ ์ธ ์‚ฌ์šฉ์ž๊ฐ€ ํ‰๋ฌธ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ํ†ตํ•ด ์†์‰ฝ๊ฒŒ ๋กœ๊ทธ์ธํ•˜๊ฑฐ๋‚˜ ๋‹ค์–‘ํ•œ ๊ณต๊ฒฉ์„ ์‹œ๋„ํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค.

 

๋”ฐ๋ผ์„œ ๋ณด์•ˆ์„ ๊ฐ•ํ™”ํ•˜๊ธฐ ์œ„ํ•ด ๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” ์•”ํ˜ธํ™”(ํ•ด์‹ฑ) ๊ณผ์ •์„ ๊ฑฐ์ณ ์ €์žฅํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•ด์‹ฑ์„ ํ†ตํ•ด ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์•”ํ˜ธํ™”ํ•˜๋ฉด, ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค ์œ ์ถœ ์‹œ์—๋„ ๋น„๋ฐ€๋ฒˆํ˜ธ ์›๋ฌธ์ด ์•„๋‹Œ ํ•ด์‹œ๊ฐ’์ด ๋…ธ์ถœ๋˜๋ฏ€๋กœ ๋ณด์•ˆ์„ ์œ ์ง€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

 

 

์˜ค๋Š˜ ํฌ์ŠคํŒ…์€ bcrypt ๋ผ์ด๋ธŒ๋Ÿฌ๋ฅผ ํ™œ์šฉํ•œ ๋ฏผ๊ฐํ•œ ์ •๋ณด๋ฅผ ์•”ํ˜ธํ™”ํ•˜์—ฌ, ๊ด€๋ฆฌํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์•Œ์•„๋ณด๋„๋ก ํ•ฉ์‹œ๋‹ค.

 

 

 

1) Node.js ํ”„๋กœ์ ํŠธ์— bcrypt๋ผ๋Š” ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ๋ฅผ ์„ค์น˜

npm install bcrypt

 

 

2) bcrypt๋กœ ๋น„๋ฐ€๋ฒˆํ˜ธ ํ•ด์‹ฑํ•˜๊ธฐ

 

- ์ฝ”๋“œ ์„ค๋ช…

1. bcrypt.hash(data.password, saltRounds): ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๋น„๋ฐ€๋ฒˆํ˜ธ์™€ salt๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์•”ํ˜ธํ™”๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

2. data.password = hashedPassword: ํ•ด์‹œ๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๋ฐ์ดํ„ฐ์— ์ €์žฅํ•˜์—ฌ ํ…์ŠคํŠธ ๋น„๋ฐ€๋ฒˆํ˜ธ ๋Œ€์‹  ์•ˆ์ „ํ•œ ํ˜•์‹์œผ๋กœ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค.

 

์ด๋ ‡๊ฒŒ ํ•ด์‹ฑํ•œ ๋น„๋ฐ€๋ฒˆํ˜ธ๋Š” ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์•ˆ์ „ํ•˜๊ฒŒ ์ €์žฅํ•  ์ˆ˜ ์žˆ์–ด, ํ•ด์ปค๊ฐ€ ์„œ๋ฒ„์— ์ ‘๊ทผํ•˜๋”๋ผ๋„ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์‰ฝ๊ฒŒ ์•Œ์•„๋‚ผ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

const bcrypt = require("bcrypt");
const saltRounds = 10; // ํ•ด์‹œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ๋ณต์žก๋„ ์„ค์ •


//ํšŒ์›๊ฐ€์ž…
const addUser = async (data) => {
  console.log("data : ", data);

  // ๋น„๋ฐ€๋ฒˆํ˜ธ ์•”ํ˜ธํ™”
  const hashedPassword = await bcrypt.hash(data.password, saltRounds);
  data.password = hashedPassword;

  return await executeQuery("UserMapper", "insertUser", data);
};

 

 

 

3)  bcrypt์™€ JWT๋ฅผ ํ™œ์šฉํ•œ ๋กœ๊ทธ์ธ ์ฒ˜๋ฆฌ

 

-์ฝ”๋“œ์„ค๋ช…

1. bcrypt.compare(data.password, user.PSWORD) : ์‚ฌ์šฉ์ž๊ฐ€ ์ž…๋ ฅํ•œ ๋น„๋ฐ€๋ฒˆํ˜ธ์™€ ๋ฐ์ดํ„ฐ๋ฒ ์ด์Šค์— ์ €์žฅ๋œ ์•”ํ˜ธํ™”๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ(user.PSWORD)๋ฅผ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค. ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ผ์น˜ํ•˜๋ฉด ๋กœ๊ทธ์ธ ์„ฑ๊ณต์œผ๋กœ ๊ฐ„์ฃผํ•˜๊ณ  ๋‹ค์Œ ๋‹จ๊ณ„๋กœ ๋„˜์–ด๊ฐ‘๋‹ˆ๋‹ค. ๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ์ผ์น˜ํ•˜์ง€ ์•Š์œผ๋ฉด "๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ๋งž์ง€ ์•Š์Šต๋‹ˆ๋‹ค"๋ผ๋Š” ์˜ค๋ฅ˜ ๋ฉ”์‹œ์ง€๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

 

2. jwt.sign() : ๋กœ๊ทธ์ธ์ด ์„ฑ๊ณตํ•˜๋ฉด jwt.sign() ํ•จ์ˆ˜๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ JWT ํ† ํฐ์„ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด ํ† ํฐ์€ ์‚ฌ์šฉ์ž ID๋ฅผ ๋‹ด์€ ํŽ˜์ด๋กœ๋“œ์™€ secretKey๋ฅผ ๋ฐ”ํƒ•์œผ๋กœ ์„œ๋ช…๋˜๋ฉฐ, ์œ ํšจ๊ธฐ๊ฐ„์€ 1์‹œ๊ฐ„(expiresIn: "1h")์œผ๋กœ ์„ค์ •๋ฉ๋‹ˆ๋‹ค.

const userLogin = async (data) => {
  const res = await executeQuery("UserMapper", "selUserLogin", data);

  if (res[0][0] != null) {
    const user = res[0][0]; // DB์—์„œ ๊ฐ€์ ธ์˜จ ์‚ฌ์šฉ์ž ์ •๋ณด
    const isPasswordCorrect = await bcrypt.compare(data.password, user.PSWORD);
    if (isPasswordCorrect) {
      // JWT ํ† ํฐ ์ƒ์„ฑ
      const token = jwt.sign({ userId: data.userId }, secretKey, {
        expiresIn: "1h",
      }); // userId๋ฅผ ํŽ˜์ด๋กœ๋“œ์— ๋‹ด๊ณ  ์œ ํšจ๊ธฐ๊ฐ„ 1์‹œ๊ฐ„ ์„ค์ •
      return {
        code: "200",
        token, // ํ† ํฐ ๋ฐ˜ํ™˜
      };
    } else {
      return { code: "400", msg: "๋น„๋ฐ€๋ฒˆํ˜ธ๊ฐ€ ๋งž์ง€ ์•Š์Šต๋‹ˆ๋‹ค." };
    }
  } else {
    return { code: "400", msg: "๋“ฑ๋ก๋œ ์ด๋ฉ”์ผ ์ •๋ณด๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค." };
  }
};

 

 

๋งˆ๋ฌด๋ฆฌ

 

์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” Node.js ํ™˜๊ฒฝ์—์„œ bcrypt์™€ JWT๋ฅผ ํ™œ์šฉํ•˜์—ฌ ์•ˆ์ „ํ•œ ์‚ฌ์šฉ์ž ๋กœ๊ทธ์ธ ๊ธฐ๋Šฅ์„ ๊ตฌํ˜„ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์‚ดํŽด๋ณด์•˜์Šต๋‹ˆ๋‹ค. ๋น„๋ฐ€๋ฒˆํ˜ธ ํ•ด์‹ฑ๊ณผ ํ† ํฐ ๊ธฐ๋ฐ˜ ์ธ์ฆ์€ ํ˜„๋Œ€ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ํ•„์ˆ˜์ ์ธ ๋ณด์•ˆ ์š”์†Œ๋กœ, ์‚ฌ์šฉ์ž ๋ฐ์ดํ„ฐ๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๋ณดํ˜ธํ•˜๋Š” ๋ฐ ํฐ ์—ญํ• ์„ ํ•ฉ๋‹ˆ๋‹ค.

 

์•ž์œผ๋กœ๋„ ๋ณด์•ˆ์— ์‹ ๊ฒฝ ์“ฐ๋ฉฐ ์‚ฌ์šฉ์ž ์ •๋ณด๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ๋ณดํ˜ธํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๊ณ„์†ํ•ด์„œ ์—ฐ๊ตฌํ•˜๊ณ  ์ ์šฉํ•ด ๋‚˜๊ฐ€๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค.
์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ฐœ๋ฐœ์— ์žˆ์–ด ๋ณด์•ˆ์€ ์„ ํƒ์ด ์•„๋‹Œ ํ•„์ˆ˜์ž„์„ ํ•ญ์ƒ ๊ธฐ์–ตํ•ด ์ฃผ์„ธ์š”.

์ด ๊ธ€์ด ์—ฌ๋Ÿฌ๋ถ„์˜ ํ”„๋กœ์ ํŠธ์— ๋„์›€์ด ๋˜๊ธฐ๋ฅผ ๋ฐ”๋ผ๋ฉฐ, ๊ถ๊ธˆํ•œ ์ ์ด ์žˆ๋‹ค๋ฉด ์–ธ์ œ๋“ ์ง€ ๋Œ“๊ธ€๋กœ ๋‚จ๊ฒจ์ฃผ์„ธ์š”. ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!