本文為 Django 登入註冊功能(後端)系列文,第 4 篇
- 新手指南|使用 Django 實現後端會員登入、註冊功能
- Django Rest Framework (DRF) 新手指南:為什麼選擇 DRF 建構 API?
- Django Rest Framework (DRF) 新手指南:用 ViewSets 快速構建 CRUD API
- Token 是什麼?網站身份驗證入門白話教學 👈所在位置
- Django REST Framework (DRF) 認證方式、預設權限規則|新手指南
- Django Rest Framework 入門指南:如何正確處理 HTTP 狀態碼
- 初學者指南:深入了解 Django 的 create_user 方法
- 新手指南:深入了解 Django 的 authenticate 方法
- Django REST Framework|@permission_classes指導手冊
- 使用 Postman 測試 Django 後端的註冊、登入與登出功能
回憶一下你人生中第一次使用 Facebook 的情形。
那時候你還不是 Facebook 使用者,於是需要註冊一個帳戶。
註冊需要填 Email 和密碼,還要設定你的名字。註冊成功後,你就有了專屬的個人檔案頁面。
接著,我們就可以靠帳號密碼來開啟 Facebook 之旅了。一切看似順理成章,但你有沒有發現:登入一次以後,很長時間都不需要再輸入帳號密碼了!
這是怎麼回事呢?讓我們一起來搞懂這個背後的技術。
為什麼需要「保持登入狀態」?
HTTP 是「失憶」的
學過網頁技術的人都聽過一句話:HTTP 是無狀態的。
但什麼叫「無狀態」?用生活例子來說:
想像你去一家很忙的餐廳點餐:
第一次:「老闆,我要一杯咖啡」
五分鐘後:「老闆,我是剛才點咖啡的客人,想加個甜點」
老闆回:「抱歉,我不記得你耶,你是誰?」
這就是 HTTP 的無狀態!每一次請求對伺服器來說都是全新的,它不會記得你之前做過什麼。
具體來說:
- 你打開了 Facebook 首頁
- 關掉網頁,再重新打開 Facebook
- 伺服器完全不知道你剛才來過,對它來說你就是陌生人
如果沒有「保持登入」會怎樣?
想像一下,如果沒有任何保持狀態的機制:
- 打開 Facebook 首頁 → 輸入帳號密碼
- 點朋友的貼文來看 → 又要輸入帳號密碼
- 想按讚 → 再輸入一次
- 留言回覆 → 繼續輸入
- 滑到下一則貼文 → 又要輸入
- 看通知 → 還是要輸入
光想就累死了對吧! 這就是為什麼我們需要解決這個問題。
核心概念:儲存
要解決這個問題,核心就是「儲存」。
基本的帳號密碼儲存
當你在 Facebook 註冊後,Facebook 會把你的帳號密碼存到資料庫。
下次登入時,就拿你輸入的去比對,對了就讓你進去。
這很單純,但問題來了:要怎麼讓你不用每次都重新輸入?
不能每次都比對密碼的原因
我們沒辦法每個動作都傳一次密碼,因為:
- 安全風險:密碼一直在網路上飛來飛去,很容易被攔截
- 效能問題:每次都查資料庫,伺服器會累死
- 體驗很差:每個動作都要等驗證,慢到你會想摔電腦
所以我們需要更聰明的方法。
最直覺的方法:瀏覽器記住密碼
自動填入功能
最直覺的想法就是:讓瀏覽器幫你記密碼。
你一定遇過這個情境:
- 第一次登入某網站
- 瀏覽器跳出來問:「要儲存這組密碼嗎?」
- 你按了儲存
- 下次來,帳密自動填好,按登入就好
看起來很完美對吧?但是…
這方法的問題
你真的放心把密碼交給瀏覽器嗎?
想像一下:
- 你的銀行密碼存在瀏覽器裡
- 你的社群帳號密碼存在瀏覽器裡
- 你的公司信箱密碼存在瀏覽器裡
如果有一天你的電腦被駭了呢?
查看儲存的密碼有多簡單?
在 Chrome 裡面:設定 → 自動填入 → 密碼 → 點眼睛圖示
就能看到所有明文密碼。雖然要輸入電腦密碼,但如果駭客已經控制你的電腦…
其他風險
- 瀏覽器本身可能有漏洞
- 多裝置同步時,一台被駭全部遭殃
- Google 帳號或 Apple ID 被盜,所有密碼都曝光
根本問題沒解決
就算瀏覽器能安全地記住密碼,還是沒解決 HTTP 無狀態的問題。
自動填入只是讓「登入動作」變簡單,但如果每個請求都要帶密碼:
- 看貼文要傳密碼
- 按讚要傳密碼
- 留言要傳密碼
密碼在網路上飛來飛去,風險超高。而且伺服器每次都要查資料庫驗證,效能也很差。
所以我們需要更好的方案!
這時候就要來聊聊「Token」這個概念了。
Token 是什麼?
其實你早就在用了
Token 這個字,有人翻成「權杖」「令牌」,聽起來很玄。
但其實 Token 就是「用來證明你身份的東西」,就這麼簡單。
你可以把它想像成生活中的各種「證明」:
- 學生證 → 證明你是這間學校的學生
- 門禁卡 → 證明你可以進這棟大樓
- 電影票 → 證明你有資格進這個影廳
在網路世界裡,Token 就是扮演這個角色。
哪些東西算 Token?
你的密碼?那就是一種 Token。
簡訊驗證碼?也是一種 Token。
系統發給你的一串亂碼?還是 Token。
只要是拿來「證明你是你」的,都叫 Token。
那為什麼還要學?
因為 Token 有很多種,有些比較安全,有些比較方便,有些兩者兼具。
就像生活中:
- 學生證可以用一整個學期(長期有效)
- 電影票看完就沒用了(一次性)
- 訪客證只有當天有效(有期限)
網路世界的 Token 也是這樣,不同情境用不同類型。
了解這些,你就會知道:
- 為什麼光靠密碼不夠安全
- 為什麼轉帳要多一道簡訊驗證
- 為什麼登入一次可以維持很久不用重新登入
接下來,我們就來看看 Token 的三種類型。
Token 的三種類型
我們從最基本、你最熟悉的開始講:
第一種:固定不變的(Static)
白話說
永遠不會變,除非你自己去改它。
沒錯,就是你的密碼。
生活例子:登入密碼
- 你設密碼是
abc123 - 除非你自己改,不然永遠是
abc123 - 每次登入都輸入一樣的東西
這種有什麼問題?
還記得前面說的嗎?如果每個動作都要傳密碼:
- 看貼文要傳密碼
- 按讚要傳密碼
- 留言要傳密碼
密碼是最基本的 Token,但它沒辦法解決「保持登入」的問題:
- 不會過期:被偷走就一直能用
- 容易被猜到:很多人用生日、123456
- 每次都要傳:密碼一直在網路上飛,風險很高
所以光靠密碼,沒辦法讓你「登入一次就不用再登入」。我們需要更聰明的方式!
第二種:一次性的(Event-based)
白話說
用一次就作廢,像電影票一樣,撕掉就不能再用了。
生活例子:轉帳的簡訊驗證碼
- 你在網銀按下「轉帳」
- 手機收到簡訊,上面有 6 位數字
- 你輸入那串數字
- 轉帳成功,那串數字就沒用了
這就是一次性 Token。用完即丟,就算有人偷看到也來不及用。
常見名詞
這種叫 OTP(One-Time Password,一次性密碼)。
下次聽到「OTP」就知道是這種用一次就丟的驗證碼。
解決了什麼問題?
比起固定密碼,OTP 更安全,因為就算被看到也沒用。
但它也沒辦法解決「保持登入」的問題——你總不能每按一次讚,就發一次簡訊驗證碼吧?
OTP 通常是用來「加強驗證」的,例如轉帳、修改密碼這種重要操作才會用到。
第三種:有期限的(Time-based)
白話說
有使用期限,時間到就過期,像超商折價券寫著「限期使用」。
生活例子:忘記密碼的重設連結
- 你按「忘記密碼」
- 收到一封 Email,裡面有連結
- 信裡寫「此連結 24 小時內有效」
- 超過 24 小時?不好意思,請重新申請
那個連結裡就藏著有期限的 Token。
這種最常見!也是解答!
還記得文章開頭的問題嗎?
「為什麼登入一次以後,很長時間都不需要再輸入帳號密碼了?」
答案就是這種 Token!
當工程師說「Token」的時候,十之八九是講這種。
它怎麼解決「保持登入」的問題?
流程是這樣:
- 你輸入帳號密碼登入(只有這次需要密碼)
- 伺服器確認正確後,發給你一個「有期限的 Token」
- 瀏覽器自動幫你保存這個 Token
- 之後你做任何事,瀏覽器會自動帶上這個 Token
- 伺服器看到 Token,就知道「喔,是你啊」,不用再問密碼
等等,這跟「瀏覽器記住密碼」有什麼不同?
你可能會想:「Token 存在瀏覽器,密碼也可以存在瀏覽器,這有差嗎?」
差很多!
「瀏覽器記住密碼」只是幫你自動填入登入表單,讓你不用手動打字而已。但如果沒有 Token 機制,理論上每個動作都要重新驗證身份。
讓我用表格說明「有 Token」跟「沒有 Token」的差別:
| 沒有 Token(假設) | 有 Token | |
|---|---|---|
| 按讚時傳什麼? | 傳密碼 | 傳 Token |
| 留言時傳什麼? | 傳密碼 | 傳 Token |
| 密碼會曝光嗎? | 每個動作都在傳密碼,風險高 | 只有登入時傳一次密碼,風險低 |
| 被偷了怎麼辦? | 完蛋,密碼直接曝光 | 損失有限,Token 會過期 |
| 內容是什麼? | 你自己設的密碼 | 伺服器發的亂碼,猜不到 |
用白話說就是…
沒有 Token:像是每次進門都要報上你的身分證字號,一直講一直講,很容易被旁邊的人聽到。
有 Token:像是用身分證換一張「臨時通行證」,之後只要出示通行證就好。就算通行證被偷,小偷也不知道你的身分證字號,而且通行證過幾天就失效了。
所以 Token 的重點是:用一個「會過期的替身」來代替「永久的密碼」,降低風險。
為什麼這種最好?
回頭看看前面提到的問題,這種 Token 全都解決了:
| 前面的問題 | Time-based Token 怎麼解決 |
|---|---|
| 密碼一直在網路上傳很危險 | 密碼只傳一次,之後都用 Token |
| 密碼被偷就完蛋 | Token 會過期,被偷也有時限 |
| 每次都查資料庫,效能很差 | 伺服器驗證 Token 比查密碼快很多 |
| HTTP 無狀態,不記得你是誰 | Token 就是讓伺服器「記得你」的方式 |
這就是為什麼你登入 Facebook 一次,就可以一直用,不用每個動作都重新輸入密碼!
快速對照表
| 類型 | 一句話解釋 | 生活例子 | 常見名詞 |
|---|---|---|---|
| 固定的 | 不改就不會變 | 你的密碼 | Password、API Key |
| 一次性 | 用一次就作廢 | 轉帳簡訊驗證碼 | OTP |
| 有期限 | 時間到就過期 | 忘記密碼連結 | JWT、Session |
常見技術歸類
聽過這些名詞的話,以下幫你分類:
固定不變的
- 你的密碼
- API Key(工程師串接服務用的金鑰)
一次性(OTP 類)
- 銀行轉帳簡訊驗證碼
- Google 兩步驟驗證的數字
有期限的
- JWT(工程師常用的 Token 格式)
- Session(網站記住你登入狀態的機制)
- 忘記密碼的重設連結
重點整理
- HTTP 是失憶的,每次請求伺服器都不認識你
- 瀏覽器記密碼只是讓輸入變簡單,沒解決根本問題
- Token 就是通行證,登入一次拿到通行證,之後出示通行證就好
- 三種類型:
- 固定的 → 你的密碼
- 一次性(OTP)→ 用完就丟
- 有期限 → 會過期
結語
現在你知道了!為什麼登入一次就能一直用,就是因為伺服器發了一張「通行證」給你。
下次收到簡訊驗證碼,或看到「連結 24 小時內有效」,你就知道背後是怎麼一回事了!