# Day 8 - 臉書的登入/登出到底怎麼做的?:JWT 與 LocalStorage ## 劇情背景 你正在測試 LiveFit 的功能,發現登入之後關掉瀏覽器,再打開還是登入狀態。 「奇怪,系統怎麼知道我是誰?」你忍不住問。 海克絲走過來:「好問題!你發現了一個很重要的現象。」 「這不是理所當然的嗎?每個網站登入後都這樣啊。」 海克絲搖搖頭:「其實 HTTP 本身是『無狀態』的——每次請求都是獨立的,伺服器根本不會記得你是誰!」 「蛤?那為什麼我不用每次都重新登入?」 海克絲露出神秘的微笑:「這就要講到今天的主題了——JWT 和 LocalStorage!」  --- ## 學習目標 - 一、理解為什麼需要身份驗證(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 服務延伸學習  --- ## 海克絲的叮嚀 > 「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`)
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up