iT邦幫忙

2026 iThome 鐵人賽

DAY 22
0
JavaScript

不要再說你不會後端!30 天 Node.js 降維打擊指南 系列 第 22 篇

Day 22:伺服器的終極防禦(密碼加密 Bcrypt 與環境變數 dotenv)

  • 分享至 

  • xImage
  •  

在昨天的 JWT 教學中,我們把伺服器的最高機密 SECRET_KEY 直接寫死在程式碼裡。這在真實開發中是絕對禁止的死罪!一旦你把程式碼上傳到 GitHub,全世界的駭客都能用這把鑰匙偽造 JWT 通行證,直接接管你的系統。

同時,把使用者的「明文密碼(如 123456)」直接存進資料庫也是另一項死罪。今天,我們要來學習後端工程師必備的兩大防禦護盾:環境變數 (dotenv) 與 密碼加密 (Bcrypt)。


1. 環境變數:隱藏伺服器的機密 (dotenv)

我們需要把所有機密(資料庫密碼、JWT 密鑰、API 金鑰)從程式碼中抽離出來,放在一個外部的隱藏檔案裡。

步驟 1:安裝 dotenv

npm install dotenv

步驟 2:建立 .env 檔案
在專案的根目錄下,建立一個名為 .env 的檔案(前面有一個點)。這個檔案絕對不能上傳到 Git!
在裡面寫入你的機密資訊(注意:變數名稱通常全大寫,且不需要加引號):

PORT=3000
JWT_SECRET=my_super_secret_key_dont_tell_anyone
DB_URL=mongodb+srv://admin:1234@cluster0...

步驟 3:在程式碼中讀取 (ES Modules 寫法)
建立一個 config-demo.js:

// 只要在最上方引入這行,dotenv 就會自動把 .env 的內容塞進 process.env 裡
import 'dotenv/config'; 

console.log("我的伺服器 Port 是:", process.env.PORT);
console.log("我的 JWT 密鑰是:", process.env.JWT_SECRET);

2. 密碼加密:單向雜湊的藝術 (Bcrypt)

就算你的資料庫被駭客整包偷走,只要你做了正確的加密,駭客看到的也會是一堆毫無意義的亂碼。我們使用的是業界標準的 Bcrypt 演算法,它不僅能進行「單向雜湊(Hash,無法反向解密)」,還會自動加入「鹽巴(Salt,隨機字串)」,讓同樣是設定 1234 密碼的兩個人,在資料庫裡的亂碼長得完全不一樣!

步驟 1:安裝 bcrypt

npm install bcrypt

步驟 2:加密與驗證實作
建立一個 crypto-demo.js:

import bcrypt from 'bcrypt';

const passwordDemo = async () => {
    const userPassword = "my_password_123";

    // --- 1. 註冊時:加密密碼 (Hash) ---
    // 數字 10 代表「鹽巴的複雜度 (Salt Rounds)」,數字越大越難破解,但加密時間也越長 (10 是業界標準)
    console.log(" 正在加密密碼...");
    const hashedPassword = await bcrypt.hash(userPassword, 10);
    
    console.log(" 準備存入資料庫的密碼:", hashedPassword);
    // 你會看到類似:$2b$10$Xo9.w8Z... 這樣的亂碼

    // --- 2. 登入時:比對密碼 (Compare) ---
    console.log("\n--- 模擬登入比對 ---");
    const loginInput1 = "wrong_password";
    const loginInput2 = "my_password_123";

    // 使用 bcrypt.compare(使用者輸入的明文, 資料庫裡的亂碼)
    const isMatch1 = await bcrypt.compare(loginInput1, hashedPassword);
    console.log(` 輸入 ${loginInput1} 的比對結果:`, isMatch1); // false

    const isMatch2 = await bcrypt.compare(loginInput2, hashedPassword);
    console.log(` 輸入 ${loginInput2} 的比對結果:`, isMatch2); // true
};

passwordDemo();

3. 結合實戰:安全的註冊與登入流程

將我們這幾天學到的 JWT、Bcrypt 與 MongoDB 結合起來,這就是現代後端系統最標準的會員流程:

  • 【註冊 API】:
    1. 接收前端傳來的帳號與明文密碼。
    2. 使用 bcrypt.hash() 加密密碼。
    3. 將帳號與加密後的亂碼存入資料庫。
  • 【登入 API】:
    1. 接收前端傳來的帳號與明文密碼。
    2. 去資料庫找出該帳號,並取出當時存入的亂碼。
    3. 使用 bcrypt.compare() 比對密碼是否正確。
    4. 比對成功後,讀取 process.env.JWT_SECRET。
    5. 使用 jwt.sign() 產生通行證 (Token) 回傳給前端。

具備了環境變數的隱蔽性與密碼加密的防護,你的 API 現在已經達到了商業級別的基礎安全標準了!


上一篇
Day 21:JWT (JSON Web Token) 身分驗證機制的魔法
下一篇
Day 23:中介軟體 (Middleware) 實戰與錯誤處理機制
系列文
不要再說你不會後端!30 天 Node.js 降維打擊指南 共 23 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言