---
# System prepended metadata

title: Day 8 - 臉書的登入/登出到底怎麼做的？：JWT 與 LocalStorage、Cookie
tags: [2026 後端工程師體驗營]

---

# Day 8 - 臉書的登入/登出到底怎麼做的？：JWT 與 LocalStorage

## 劇情背景

你正在測試 LiveFit 的功能，發現登入之後關掉瀏覽器，再打開還是登入狀態。

「奇怪，系統怎麼知道我是誰？」你忍不住問。

海克絲走過來：「好問題！你發現了一個很重要的現象。」

「這不是理所當然的嗎？每個網站登入後都這樣啊。」

海克絲搖搖頭：「其實 HTTP 本身是『無狀態』的——每次請求都是獨立的，伺服器根本不會記得你是誰！」

「蛤？那為什麼我不用每次都重新登入？」

海克絲露出神秘的微笑：「這就要講到今天的主題了——JWT 和 LocalStorage！」


![截圖 2026-01-21 下午2.23.12](https://hackmd.io/_uploads/ryefZeArbe.png)


---

## 學習目標

- 一、理解為什麼需要身份驗證（HTTP 無狀態）
- 二、認識 JWT（JSON Web Token）的原理
- 三、了解瀏覽器的兩個儲物櫃：LocalStorage 和 Cookie
- 四、學會用 Chrome DevTools 查看 LocalStorage 和 Cookie
- 五、理解 JWT 的安全性與過期機制

---

## 核心概念

### 一、HTTP 是無狀態的

每次你發送請求，伺服器都不記得你是誰。就像每次進便利商店，店員都不認識你一樣。

**想像一下：**
- 你說「用我的會員點數折抵」
- 店員說「你是誰？」

這就是 HTTP 的特性！所以我們需要一個機制，讓伺服器「記得」你是誰。
補充：HTTP 的中文是「超文本傳輸協定」，意思是瀏覽器與伺服器之間溝通的標準規則

### 二、JWT 是什麼？用餐廳號碼牌來理解

JWT（JSON Web Token）就像餐廳的「號碼牌」。是一種經過加密簽名的字串格式，用來安全地傳遞資訊。

**想像你在預約餐廳：**

1. **你填寫預約資料**（姓名、人數、時間、備註「我要靠窗座位」）
2. **餐廳給你一組號碼牌：12 號**
3. **到了餐廳，你只要說「我是 12 號」**
4. **服務生查號碼就知道你的所有資料**，不用重複問你是誰、幾點、幾個人

這就是 JWT 的運作方式！

- **你的預約資料** = JWT 的 Payload（內容）
- **12 號** = JWT Token
- **餐廳的防偽章** = JWT 的 Signature（簽名）

### 為什麼 JWT 無法被偽造？

假設有人想偽造一張「12 號」號碼牌混進去吃飯：

- **問題**：餐廳的號碼牌上有特殊的「防偽章」
- **防偽章怎麼做的？** 餐廳用只有他們知道的「秘密印章」蓋上去
- **驗證方式**：服務生一看防偽章，就知道是不是真的

**技術上：** 只有伺服器知道「密鑰」（JWT_SECRET），如果有人竄改內容，簽名就會對不上，伺服器驗證時會發現「這張號碼牌是假的！」

### 秘密金鑰要放在哪裡？

秘密金鑰（JWT_SECRET）就像餐廳的秘密印章，絕對不能讓別人知道！

**錯誤做法：** 把金鑰直接寫在程式碼裡 → 就像把家裡鑰匙貼在大門上

**正確做法：** 放進「保險箱」檔案！
- 這個保險箱叫做 `.env`（唸作 dot env）
- 用 `.gitignore` 防止上傳到 GitHub
- 只有自己的電腦看得到

```
# .env 檔案範例
JWT_SECRET=hexschool666
JWT_EXPIRES_DAY=30d
```

這就是 JWT 的運作方式！

1. JWT 的 **Header（標頭）** = 號碼牌的類型 (加密規則，有了規則伺服器才能解析)
2. JWT 的 **Payload （內容）**= 你的預約資料（姓名、人數）
3. JWT 的 **Signature（簽名**）= 餐廳的防偽章（防止偽造）

這 3 個部分組合起來就是「12 號」這張號碼牌 = JWT Token
### 後端怎麼幫你蓋章？

當你登入時，**後端程式（Node.js）** 會負責產生 JWT：

1. **你輸入帳號密碼登入**
2. **後端驗證帳密正確**
3. **Node.js 從 .env 拿出秘密印章（JWT_SECRET）**
4. **把你的資料 + 秘密印章 → 產生 JWT**
5. **JWT 回傳給前端，存進 LocalStorage**

之後每次你發 API 請求，都要在 HTTP Request Header 帶上這張 JWT，後端才知道「是誰在操作」。

- （Header + Payload + JWT_SECRET）X 加密規則 (Header) = JWT 的 Signature
- Header + Payload + Signature = JWT Token (號碼牌)
- JWT Token 會被存放在**使用者**的瀏覽器的 LocalStorage 或 cookie 裡面
- JWT_SECRET (秘密印帳) 會被存放在 .env 檔案當中，.env 檔案會存在**伺服器**裡面
- 每次瀏覽器發出 API 請求時，前端程式碼就會去 LocalStorage 取出 JWT Token 並放到 HTTP Request Header 提供給伺服器
- HTTP Request Header → 瀏覽器要提供給伺服器的資訊會放在這邊
- JWT Header → 是指這個 JWT 的加密類型（可能是某種數學公式）讓伺服器收到後知道如何解析這段 JWT
### 三、瀏覽器的兩個儲物櫃

前端拿到 JWT 後，要存在哪裡？瀏覽器有兩個常用的「儲物櫃」：

| 特性 | LocalStorage | Cookie |
|------|--------------|--------|
| 容量 | 約 5MB | 約 4KB |
| 自動帶上請求 | ❌ 不會，要手動加 | ✅ 會自動送給伺服器 |
| 過期時間 | 永久（除非手動刪除） | 可設定 |

**LiveFit 用的是 LocalStorage**，因為前端可以自己控制什麼時候要帶 Token。

### 四、用 Chrome DevTools 查看 LocalStorage

想看瀏覽器存了什麼資料？很簡單！

1. **打開開發者工具**：按 F12（或右鍵 → 檢查）
2. **點選 Application 面板**
3. **展開左側的 Storage → Local Storage**
4. **點擊網域名稱**，右邊就會顯示儲存的資料

在這裡你可以看到 JWT Token！

### 五、Token 過期機制

你的預約號碼牌上寫著「限當日有效」，這就是過期機制。

**為什麼要過期？**
- 萬一你的號碼牌被別人撿到，至少明天就失效了
- 伺服器不用永遠記得「12 號是誰」

**JWT 也一樣：**
- 過期後，使用者需要重新登入（重新預約拿新號碼牌）
- LiveFit 設定 30 天過期（`JWT_EXPIRES_DAY=30d`）

### 安全小提醒

JWT 就像鑰匙，被偷走別人就能冒充你！

**在公司特別要注意：**
- 如果離開電腦沒鎖定...
- 別人可能打開 DevTools 複製你的 JWT
- 貼到自己電腦就能用你的身份登入！

**解決方法：**
- 離開電腦前記得鎖定螢幕
- Mac：`Cmd + Ctrl + Q`
- Windows：`Win + L`

---

## 測驗題目預覽 (共 10 題)

### JWT 觀念篇 (7 題)

1. 為什麼關掉瀏覽器後重新打開，網站還是維持登入狀態？
2. JWT 的全名是什麼？
3. 為什麼別人無法偽造你的 JWT？
4. 後端的秘密金鑰（用來蓋防偽章的印章）應該放在哪裡？
5. LocalStorage 和 Cookie 有什麼差異？
6. 登入成功後，後端會回傳什麼給前端？
7. JWT 號碼牌過期後會怎樣？

### 實務應用篇 (3 題)

8. 在 Chrome 開發者工具中，要去哪裡看 LocalStorage 的內容？
9. 如果手動刪除瀏覽器裡存的 JWT（號碼牌），會發生什麼事？
10. 為什麼離開電腦前要記得鎖定螢幕？

---

## 遊戲連結

請進入遊戲完成本日關卡：

👉 **[點此進入遊戲](https://hexschool.github.io/backend-camp-game/)**

## 回報格式(確認打卡細節)

1. 完成遊戲中的測驗並截圖完成畫面
2. 到體驗營 Discord 的[每日活動頻道](https://discord.com/channels/801807326054055996/1446368763581562880)，找到當天任務的討論串
3. 在討論串留言貼上截圖，打卡儀表板會自動記錄你的成績
4. 分享一下此關卡有哪些知識點讓你印象深刻，甚至有透過 AI 服務延伸學習

![截圖 2026-01-02 下午5.16.29](https://hackmd.io/_uploads/BJig6WSEZg.png)
---

## 海克絲的叮嚀

> 「JWT 讓我們可以在不查詢資料庫的情況下驗證使用者身份，效能很好。但要記住，Token 就像鑰匙，被偷走別人就能冒充你。所以要注意：JWT_SECRET 放在 .env、設定合理的過期時間、離開電腦記得鎖定螢幕！」

---

## 重點整理

### 今天學到的概念

1. **HTTP 無狀態** = 伺服器每次請求都不記得你是誰 
3. **JWT** = 像餐廳號碼牌，登入時後端給你，之後每次請求都帶著它
4. **防偽章（Signature）** = 用秘密金鑰產生，別人無法偽造，是 JWT 的其中一部分
5. **JWT_SECRET(秘密金鑰)** = 要放在 .env 保險箱，用 .gitignore 防止上傳

### 瀏覽器儲物櫃

- **LocalStorage**：容量大（5MB），永久保存，不會自動帶上請求
- **Cookie**：容量小（4KB），可設過期時間，每次請求自動帶上
- **用 Application 面板**：在 Chrome DevTools 查看儲存的資料

### 安全守則

- Token 過期後需要重新登入
- 刪除 LocalStorage 的 JWT 會登出
- 離開電腦要鎖定螢幕（Mac: `Cmd+Ctrl+Q` / Windows: `Win+L`）
