[{"data":1,"prerenderedAt":849},["ShallowReactive",2],{"navigation_docs":3,"-web-dev-security-jwt-authentication":352,"-web-dev-security-jwt-authentication-surround":844},[4,54,83,116,125,161,179,200],{"title":5,"path":6,"stem":7,"children":8},"Ai","/ai","ai",[9,12,42,46,50],{"title":10,"path":6,"stem":11},"AI 技術探索","ai/index",{"title":13,"path":14,"stem":15,"children":16,"page":41},"Rag","/ai/rag","ai/RAG",[17,21,25,29,33,37],{"title":18,"path":19,"stem":20},"BM25 演算法深入解析：從 TF-IDF 到現代搜尋引擎的核心技術","/ai/rag/bm25-deep-dive-from-tf-idf-to-rag","ai/RAG/bm25-deep-dive-from-tf-idf-to-rag",{"title":22,"path":23,"stem":24},"Dense Retrieval（向量檢索）深入解析","/ai/rag/dense-retrieval-deep-dive","ai/RAG/dense-retrieval-deep-dive",{"title":26,"path":27,"stem":28},"RAG（Retrieval-Augmented Generation）原理與實作入門","/ai/rag/rag-intro-principles-and-implementation","ai/RAG/rag-intro-principles-and-implementation",{"title":30,"path":31,"stem":32},"RAG Retrieval Strategy 深入解析","/ai/rag/rag-retrieval-strategy-deep-dive","ai/RAG/rag-retrieval-strategy-deep-dive",{"title":34,"path":35,"stem":36},"Reciprocal Rank Fusion（RRF）教學：打造更穩定的檢索融合策略","/ai/rag/rrf-reciprocal-rank-fusion-guide","ai/RAG/rrf-reciprocal-rank-fusion-guide",{"title":38,"path":39,"stem":40},"TF-IDF（Term Frequency–Inverse Document Frequency）深入解析","/ai/rag/tf-idf-deep-dive","ai/RAG/tf-idf-deep-dive",false,{"title":43,"path":44,"stem":45},"Docus AI 功能完整實作指南","/ai/docus-ai-implementation","ai/docus-ai-implementation",{"title":47,"path":48,"stem":49},"llms.txt 是什麼？在 Nuxt 中控制 AI 與搜尋引擎爬蟲的新方式","/ai/llms-txt","ai/llms-txt",{"title":51,"path":52,"stem":53},"MCP（Model Context Protocol）是什麼？用「AI 的 USB-C」理解模型如何安全連接工具與資料","/ai/mcp_concept","ai/mcp_concept",{"title":55,"path":56,"stem":57,"children":58,"page":41},"Data Analysis","/data-analysis","data-analysis",[59,63,67,71,75,79],{"title":60,"path":61,"stem":62},"Exploratory Data Analysis（EDA）資料探索分析入門","/data-analysis/exploratory-data-analysis-eda","data-analysis/exploratory-data-analysis-eda",{"title":64,"path":65,"stem":66},"PR-AUC 深入解析：不平衡分類問題的重要評估指標","/data-analysis/pr-auc-for-imbalanced-classification","data-analysis/pr-auc-for-imbalanced-classification",{"title":68,"path":69,"stem":70},"ROC-AUC 深入解析：理解分類模型的判斷能力","/data-analysis/roc-auc-complete-guide","data-analysis/roc-auc-complete-guide",{"title":72,"path":73,"stem":74},"SHAP（SHapley Additive exPlanations）模型解釋方法深入解析","/data-analysis/shap-model-interpretation-complete-guide","data-analysis/shap-model-interpretation-complete-guide",{"title":76,"path":77,"stem":78},"Social Network Analysis（SNA）深入解析","/data-analysis/social-network-analysis-sna","data-analysis/social-network-analysis-sna",{"title":80,"path":81,"stem":82},"Time-based Split：為什麼時間序列資料不能使用 Random Split？","/data-analysis/time-based-split-vs-random-split","data-analysis/time-based-split-vs-random-split",{"title":84,"path":85,"stem":86,"children":87,"page":41},"MachineLearning","/machine_learning","machine_learning",[88,92,96,100,104,108,112],{"title":89,"path":90,"stem":91},"Confusion Matrix（混淆矩陣）完整解析","/machine_learning/confusion-matrix","machine_learning/confusion-matrix",{"title":93,"path":94,"stem":95},"Decision Tree 模型完整教學：從原理到 Python 實作","/machine_learning/decision-tree-complete-guide","machine_learning/decision-tree-complete-guide",{"title":97,"path":98,"stem":99},"為什麼 Decision Tree 在 Tabular Data 上常常勝過 Deep Learning？","/machine_learning/decision-tree-vs-deep-learning-on-tabular-data","machine_learning/decision-tree-vs-deep-learning-on-tabular-data",{"title":101,"path":102,"stem":103},"LightGBM 模型入門：理解高效能的 Gradient Boosting 演算法","/machine_learning/lightgbm-intro-for-tabular-data","machine_learning/lightgbm-intro-for-tabular-data",{"title":105,"path":106,"stem":107},"Logistic Regression（Logit 回歸）完整教學","/machine_learning/logistic-regression-complete-guide","machine_learning/logistic-regression-complete-guide",{"title":109,"path":110,"stem":111},"為什麼模型訓練需要 Train / Validation / Test Dataset？","/machine_learning/train-validation-test-dataset","machine_learning/train-validation-test-dataset",{"title":113,"path":114,"stem":115},"XGBoost 原理與實務教學","/machine_learning/xgboost-complete-guide","machine_learning/xgboost-complete-guide",{"title":117,"path":118,"stem":119,"children":120,"page":41},"Network","/network","network",[121],{"title":122,"path":123,"stem":124},"DNS 設定入門：CNAME vs A Record 完整解析","/network/dns-cname-vs-a-record-guide","network/dns-cname-vs-a-record-guide",{"title":126,"path":127,"stem":128,"children":129},"Nuxt","/nuxt","nuxt",[130,133,137,141,145,149,153,157],{"title":131,"path":127,"stem":132},"Nuxt 實戰指南","nuxt/index",{"title":134,"path":135,"stem":136},"Abstraction Layer 與 Adapter 的差別，一次搞懂設計角色","/nuxt/adapter_abstraction_layer","nuxt/adapter_abstraction_layer",{"title":138,"path":139,"stem":140},"Nuxt 4 全面理解 — 專案檔案結構解析","/nuxt/directory_structure","nuxt/directory_structure",{"title":142,"path":143,"stem":144},"Nuxt 前端 build 流程完整解析","/nuxt/frontend_build","nuxt/frontend_build",{"title":146,"path":147,"stem":148},"Nitro 是什麼？從 Nuxt 專案到 Server 與 Edge 的關鍵引擎","/nuxt/nitro","nuxt/nitro",{"title":150,"path":151,"stem":152},"深入理解 Nuxt 的 .nuxt 與 .output：為什麼部署時一定要分清楚？","/nuxt/nuxt_and_output","nuxt/nuxt_and_output",{"title":154,"path":155,"stem":156},"Nuxt 中 dev、build、preview 的差異一次搞懂","/nuxt/nuxt_dev_build_preview","nuxt/nuxt_dev_build_preview",{"title":158,"path":159,"stem":160},"Nuxt Image vs \u003Cimg>：為什麼 Nuxt 3 專案幾乎都該用 \u003CNuxtImg>？","/nuxt/nuxt_image","nuxt/nuxt_image",{"title":162,"path":163,"stem":164,"children":165},"Python 程式開發","/python","python/index",[166,167,171,175],{"title":162,"path":163,"stem":164},{"title":168,"path":169,"stem":170},"如何在 FastAPI 中調用記憶體 Buffer 回傳圖片 (附實例)","/python/memory_buffer","python/memory_buffer",{"title":172,"path":173,"stem":174},"Python 單元測試教學：如何為你的程式撰寫 Test","/python/python-unit-testing-unittest-pytest","python/python-unit-testing-unittest-pytest",{"title":176,"path":177,"stem":178},"如何使用 uv 取代 pip：改善 Python 專案的開發流程","/python/uv","python/uv",{"title":180,"path":181,"stem":182,"children":183,"page":41},"Statistic","/statistic","statistic",[184,188,192,196],{"title":185,"path":186,"stem":187},"卡方檢定（Chi-Square Test）入門教學","/statistic/chi-square-test-intro","statistic/chi-square-test-intro",{"title":189,"path":190,"stem":191},"常見抽樣方法（Sampling Methods）教學：Stratified、Quota、Convenience、Systematic、Simple Random","/statistic/common-sampling-methods-guide","statistic/common-sampling-methods-guide",{"title":193,"path":194,"stem":195},"Cramér’s V 指標介紹：如何衡量兩個類別變數之間的關聯","/statistic/cramers-v-for-categorical-association","statistic/cramers-v-for-categorical-association",{"title":197,"path":198,"stem":199},"Mann–Whitney U 與 Kolmogorov–Smirnov（KS）檢定：非參數統計檢定的入門指南","/statistic/mann-whitney-u-and-ks-test-intro","statistic/mann-whitney-u-and-ks-test-intro",{"title":201,"path":202,"stem":203,"children":204},"WebDev","/web_dev","web_dev",[205,208,234,248,282,312,334],{"title":206,"path":202,"stem":207},"Web 前端開發","web_dev/index",{"title":209,"path":210,"stem":211,"children":212},"瀏覽器與渲染","/web_dev/browser","web_dev/browser/index",[213,214,218,222,226,230],{"title":209,"path":210,"stem":211},{"title":215,"path":216,"stem":217},"瀏覽器儲存空間完整解析：Cookie、localStorage、IndexedDB 到 Cache Storage","/web_dev/browser/browser-storage-comprehensive-guide","web_dev/browser/browser-storage-comprehensive-guide",{"title":219,"path":220,"stem":221},"DOM (Document Object Model) 深入解析","/web_dev/browser/dom","web_dev/browser/dom",{"title":223,"path":224,"stem":225},"Service Worker Request Flow 深入解析","/web_dev/browser/service-worker-request-flow","web_dev/browser/service-worker-request-flow",{"title":227,"path":228,"stem":229},"CSR、SSR 與 SSG 是什麼？前端渲染策略完整比較","/web_dev/browser/ssr_csr_ssg","web_dev/browser/ssr_csr_ssg",{"title":231,"path":232,"stem":233},"Virtual DOM 深入解析：為什麼它能優化前端效能？","/web_dev/browser/virtual_dom","web_dev/browser/virtual_dom",{"title":235,"path":236,"stem":237,"children":238},"圖形技術","/web_dev/graphics","web_dev/graphics/index",[239,240,244],{"title":235,"path":236,"stem":237},{"title":241,"path":242,"stem":243},"為什麼 Three.js 專案幾乎都選擇 CSR？從 SSR 問題談起","/web_dev/graphics/threejs_csr","web_dev/graphics/threejs_csr",{"title":245,"path":246,"stem":247},"WebGL 是什麼？為什麼前端 3D 幾乎都靠它？","/web_dev/graphics/webgl","web_dev/graphics/webGL",{"title":249,"path":250,"stem":251,"children":252},"架構與配置","/web_dev/infrastructure","web_dev/infrastructure/index",[253,254,258,262,266,270,274,278],{"title":249,"path":250,"stem":251},{"title":255,"path":256,"stem":257},"Zeabur + K3s + Nuxt 部署架構完整解析","/web_dev/infrastructure/k3s-zeabur","web_dev/infrastructure/K3s-zeabur",{"title":259,"path":260,"stem":261},"ECS vs Docker vs Kubernetes：從部署堆疊理解三層架構","/web_dev/infrastructure/ecs-docker-kubernetes-stack","web_dev/infrastructure/ecs-docker-kubernetes-stack",{"title":263,"path":264,"stem":265},"ECS vs VPS 是什麼？從部署網站的角度一次搞懂差別","/web_dev/infrastructure/ecs-vs-vps","web_dev/infrastructure/ecs-vs-vps",{"title":267,"path":268,"stem":269},"Zeabur 內網服務連線完整入門指南","/web_dev/infrastructure/k3s-internal-networking","web_dev/infrastructure/k3s-internal-networking",{"title":271,"path":272,"stem":273},"使用 Microservices 架構設計系統的優勢解析","/web_dev/infrastructure/microservices-architecture-advantages","web_dev/infrastructure/microservices-architecture-advantages",{"title":275,"path":276,"stem":277},"Nginx 入門教學：從反向代理到與 Kubernetes 的架構比較","/web_dev/infrastructure/nginx-intro","web_dev/infrastructure/nginx-intro",{"title":279,"path":280,"stem":281},"YAML 配置是什麼？為什麼現代開發都在用它","/web_dev/infrastructure/yaml-configuration","web_dev/infrastructure/yaml-configuration",{"title":283,"path":284,"stem":285,"children":286},"網絡與通訊","/web_dev/network","web_dev/network/index",[287,288,292,296,300,304,308],{"title":283,"path":284,"stem":285},{"title":289,"path":290,"stem":291},"HTTP Request 結構完整解析：從 Request Line 到 Header 一次看懂","/web_dev/network/http-request-structure","web_dev/network/http-request-structure",{"title":293,"path":294,"stem":295},"OSI 模型（Open Systems Interconnection Model）完整解析","/web_dev/network/osi-model","web_dev/network/osi-model",{"title":297,"path":298,"stem":299},"RESTful API 設計原則與實務解析","/web_dev/network/restful-api","web_dev/network/restful-api",{"title":301,"path":302,"stem":303},"RESTful API 五大設計原則深入解析","/web_dev/network/restful-api-principles","web_dev/network/restful-api-principles",{"title":305,"path":306,"stem":307},"Server-Sent Events (SSE) 深入解析與實作教學","/web_dev/network/sse-introduction","web_dev/network/sse-introduction",{"title":309,"path":310,"stem":311},"WebSocket 入門教學：從概念到 Node.js 實作","/web_dev/network/websocket-introduction","web_dev/network/websocket-introduction",{"title":313,"path":314,"stem":315,"children":316},"認證與安全","/web_dev/security","web_dev/security/index",[317,318,322,326,330],{"title":313,"path":314,"stem":315},{"title":319,"path":320,"stem":321},"使用 Cookie 與 Session 建立使用者驗證（完整新手教學）","/web_dev/security/cookie-session-authentication","web_dev/security/cookie-session-authentication",{"title":323,"path":324,"stem":325},"JWT 驗證機制完整解析：從登入流程到實務應用","/web_dev/security/jwt-authentication","web_dev/security/jwt-authentication",{"title":327,"path":328,"stem":329},"Secret Key 簽名是什麼？從零理解資料簽名的本質","/web_dev/security/secret-key-signing","web_dev/security/secret-key-signing",{"title":331,"path":332,"stem":333},"SSH（Secure Shell）是什麼？從遠端登入到安全通道的核心概念","/web_dev/security/ssh","web_dev/security/ssh",{"title":335,"path":336,"stem":337,"children":338},"SEO 與規範","/web_dev/seo","web_dev/seo/index",[339,340,344,348],{"title":335,"path":336,"stem":337},{"title":341,"path":342,"stem":343},"Canonical URL 是什麼？用生活化方式搞懂前端 SEO 的基本保命符","/web_dev/seo/canonical_link","web_dev/seo/canonical_link",{"title":345,"path":346,"stem":347},"robots.txt 是什麼？SEO 的第一道守門員","/web_dev/seo/robot_txt","web_dev/seo/robot_txt",{"title":349,"path":350,"stem":351},"Nuxt SEO 中的 Meta 與 SEO 工具是如何運作的？","/web_dev/seo/seo","web_dev/seo/seo",{"id":353,"title":323,"body":354,"description":830,"extension":831,"links":832,"meta":833,"navigation":841,"path":324,"seo":842,"stem":325,"__hash__":843},"docs/web_dev/security/jwt-authentication.md",{"type":355,"value":356,"toc":820},"minimark",[357,361,365,368,371,376,379,390,393,413,436,443,445,449,452,455,471,474,520,523,526,561,564,569,572,574,578,581,592,595,604,607,613,615,619,622,633,636,638,642,649,652,735,738,765,770,772,776,779,782,784,788,791,799,802,805,807,810,813,816],[358,359,323],"h1",{"id":360},"jwt-驗證機制完整解析從登入流程到實務應用",[362,363,364],"p",{},"在現代 Web 應用中，「登入系統」其實是在解決一個非常核心的問題：HTTP 不會記得使用者是誰。當瀏覽器送出每一次請求時，對伺服器而言，那都只是一次全新的 request。HTTP 是一種 stateless（無狀態）協定，它不會自動保存使用者的登入狀態，也不會知道這個請求是否來自同一個人。因此，我們需要一種機制，讓伺服器能夠辨認「這個 request 是哪個使用者發出的」。",[362,366,367],{},"在這樣的背景下，JWT（JSON Web Token）成為一種非常常見的解決方案。JWT 是一種標準格式（RFC 7519），用來在雙方之間安全地傳遞資訊，最常見的用途就是身份驗證。理解 JWT 的核心邏輯後，你會發現它其實並不複雜，它只是把「身份資訊」包裝成一個被簽名的憑證。",[369,370],"hr",{},[372,373,375],"h2",{"id":374},"jwt-的基本結構與概念","JWT 的基本結構與概念",[362,377,378],{},"JWT 通常長得像這樣：",[380,381,387],"pre",{"className":382,"code":384,"language":385,"meta":386},[383],"language-text","xxxxx.yyyyy.zzzzz\n","text","",[388,389,384],"code",{"__ignoreMap":386},[362,391,392],{},"它由三個部分組成：",[380,394,398],{"className":395,"code":396,"language":397,"meta":386,"style":386},"language-css shiki shiki-themes github-dark","header.payload.signature\n","css",[388,399,400],{"__ignoreMap":386},[401,402,405,409],"span",{"class":403,"line":404},"line",1,[401,406,408],{"class":407},"s4JwU","header",[401,410,412],{"class":411},"svObZ",".payload.signature\n",[414,415,416,424,430],"ul",{},[417,418,419,423],"li",{},[420,421,422],"strong",{},"Header","：主要說明簽名演算法，例如常見的 HS256。",[417,425,426,429],{},[420,427,428],{},"Payload","：包含實際資料，例如 userId、角色、過期時間（exp）。",[417,431,432,435],{},[420,433,434],{},"Signature","：伺服器使用 secret key 對前兩段資料進行簽名後產生的結果。",[362,437,438,439,442],{},"這裡最重要的一個觀念是：",[420,440,441],{},"JWT 的重點不是加密，而是簽名。"," 簽名的作用在於確保資料沒有被竄改。只要 payload 被修改，signature 就會失效。伺服器不需要相信 client 傳來的內容本身，而是透過驗證 signature 來確認這份資料確實是自己簽發的。",[369,444],{},[372,446,448],{"id":447},"從登入開始看-jwt-的完整生命週期","從登入開始看 JWT 的完整生命週期",[362,450,451],{},"我們可以從使用者登入的那一刻開始，一步一步走完整個 JWT 的 lifecycle。",[362,453,454],{},"當使用者在瀏覽器中輸入帳號密碼，前端會送出一個 HTTP request，例如：",[380,456,460],{"className":457,"code":458,"language":459,"meta":386,"style":386},"language-bash shiki shiki-themes github-dark","POST /login\n","bash",[388,461,462],{"__ignoreMap":386},[401,463,464,467],{"class":403,"line":404},[401,465,466],{"class":411},"POST",[401,468,470],{"class":469},"sU2Wk"," /login\n",[362,472,473],{},"Request body 可能長這樣：",[380,475,479],{"className":476,"code":477,"language":478,"meta":386,"style":386},"language-json shiki shiki-themes github-dark","{\n  \"username\": \"damien\",\n  \"password\": \"1234\"\n}\n","json",[388,480,481,487,503,514],{"__ignoreMap":386},[401,482,483],{"class":403,"line":404},[401,484,486],{"class":485},"s95oV","{\n",[401,488,490,494,497,500],{"class":403,"line":489},2,[401,491,493],{"class":492},"sDLfK","  \"username\"",[401,495,496],{"class":485},": ",[401,498,499],{"class":469},"\"damien\"",[401,501,502],{"class":485},",\n",[401,504,506,509,511],{"class":403,"line":505},3,[401,507,508],{"class":492},"  \"password\"",[401,510,496],{"class":485},[401,512,513],{"class":469},"\"1234\"\n",[401,515,517],{"class":403,"line":516},4,[401,518,519],{"class":485},"}\n",[362,521,522],{},"伺服器收到這個請求後，會查詢資料庫，驗證密碼是否正確。如果驗證成功，伺服器取得使用者的識別資訊，例如 userId = 42。",[362,524,525],{},"接著，伺服器會建立一個 JWT。Payload 可能包含：",[380,527,529],{"className":476,"code":528,"language":478,"meta":386,"style":386},"{\n  \"userId\": 42,\n  \"exp\": 1730000000\n}\n",[388,530,531,535,547,557],{"__ignoreMap":386},[401,532,533],{"class":403,"line":404},[401,534,486],{"class":485},[401,536,537,540,542,545],{"class":403,"line":489},[401,538,539],{"class":492},"  \"userId\"",[401,541,496],{"class":485},[401,543,544],{"class":492},"42",[401,546,502],{"class":485},[401,548,549,552,554],{"class":403,"line":505},[401,550,551],{"class":492},"  \"exp\"",[401,553,496],{"class":485},[401,555,556],{"class":492},"1730000000\n",[401,558,559],{"class":403,"line":516},[401,560,519],{"class":485},[362,562,563],{},"其中 exp 代表過期時間。然後伺服器使用 secret key 進行簽名，產生最終的 token：",[380,565,567],{"className":566,"code":384,"language":385,"meta":386},[383],[388,568,384],{"__ignoreMap":386},[362,570,571],{},"這個 token 就是「身份憑證」。",[369,573],{},[372,575,577],{"id":576},"token-如何在後續請求中發揮作用","Token 如何在後續請求中發揮作用",[362,579,580],{},"當伺服器將 token 回傳給前端後，前端會把它儲存起來。儲存方式可能是 localStorage、cookie 或記憶體。接下來，只要呼叫需要登入權限的 API，前端就會在 HTTP header 中帶上：",[380,582,586],{"className":583,"code":584,"language":585,"meta":386,"style":386},"language-makefile shiki shiki-themes github-dark","Authorization: Bearer \u003Ctoken>\n","makefile",[388,587,588],{"__ignoreMap":386},[401,589,590],{"class":403,"line":404},[401,591,584],{},[362,593,594],{},"例如：",[380,596,598],{"className":583,"code":597,"language":585,"meta":386,"style":386},"Authorization: Bearer eyJhbGciOiJIUzI1NiIs...\n",[388,599,600],{"__ignoreMap":386},[401,601,602],{"class":403,"line":404},[401,603,597],{},[362,605,606],{},"當伺服器收到這個 request 時，會做幾件事情：解析 Authorization header、驗證 signature、檢查 exp 是否過期，最後從 payload 中取得 userId。如果所有檢查都通過，這個 request 就會被視為「已登入使用者發出」。",[362,608,609,610],{},"整個流程可以用一句話總結：\n",[420,611,612],{},"登入成功 → server 簽發 JWT → client 儲存 → request 帶 token → server 驗證 → 辨認使用者。",[369,614],{},[372,616,618],{"id":617},"為什麼-jwt-不需要-session","為什麼 JWT 不需要 Session？",[362,620,621],{},"在傳統的 session-based 驗證中，伺服器會保存一份 session 狀態，例如把 sessionId 存在記憶體或資料庫中。每次請求都必須查詢 session store，確認這個使用者是否仍然登入。",[362,623,624,625,628,629,632],{},"而 JWT 的特點是：",[420,626,627],{},"身份資訊本身就包含在 token 裡面","。伺服器只要驗證 signature，就能信任 payload 的內容。這種方式稱為 ",[420,630,631],{},"stateless authentication","。",[362,634,635],{},"也就是說，伺服器不需要保存登入狀態。每次驗證都是根據 token 本身完成。這讓系統在水平擴展（例如多台 server、microservices 架構）時更加容易，因為不需要共享 session store。",[369,637],{},[372,639,641],{"id":640},"使用-nodejs-實作-jwt概念示範","使用 Node.js 實作 JWT（概念示範）",[362,643,644,645,648],{},"在 Node.js 中，常見的做法是使用 ",[388,646,647],{},"jsonwebtoken"," 套件來處理簽發與驗證。",[362,650,651],{},"建立 token 的方式大致如下：",[380,653,657],{"className":654,"code":655,"language":656,"meta":386,"style":386},"language-js shiki shiki-themes github-dark","const jwt = require(\"jsonwebtoken\");\nconst token = jwt.sign(\n  { userId: 42 },\n  SECRET,\n  { expiresIn: \"1h\" }\n);\n","js",[388,658,659,683,701,711,718,730],{"__ignoreMap":386},[401,660,661,665,668,671,674,677,680],{"class":403,"line":404},[401,662,664],{"class":663},"snl16","const",[401,666,667],{"class":492}," jwt",[401,669,670],{"class":663}," =",[401,672,673],{"class":411}," require",[401,675,676],{"class":485},"(",[401,678,679],{"class":469},"\"jsonwebtoken\"",[401,681,682],{"class":485},");\n",[401,684,685,687,690,692,695,698],{"class":403,"line":489},[401,686,664],{"class":663},[401,688,689],{"class":492}," token",[401,691,670],{"class":663},[401,693,694],{"class":485}," jwt.",[401,696,697],{"class":411},"sign",[401,699,700],{"class":485},"(\n",[401,702,703,706,708],{"class":403,"line":505},[401,704,705],{"class":485},"  { userId: ",[401,707,544],{"class":492},[401,709,710],{"class":485}," },\n",[401,712,713,716],{"class":403,"line":516},[401,714,715],{"class":492},"  SECRET",[401,717,502],{"class":485},[401,719,721,724,727],{"class":403,"line":720},5,[401,722,723],{"class":485},"  { expiresIn: ",[401,725,726],{"class":469},"\"1h\"",[401,728,729],{"class":485}," }\n",[401,731,733],{"class":403,"line":732},6,[401,734,682],{"class":485},[362,736,737],{},"驗證 token 時則使用：",[380,739,741],{"className":654,"code":740,"language":656,"meta":386,"style":386},"const payload = jwt.verify(token, SECRET);\n",[388,742,743],{"__ignoreMap":386},[401,744,745,747,750,752,754,757,760,763],{"class":403,"line":404},[401,746,664],{"class":663},[401,748,749],{"class":492}," payload",[401,751,670],{"class":663},[401,753,694],{"class":485},[401,755,756],{"class":411},"verify",[401,758,759],{"class":485},"(token, ",[401,761,762],{"class":492},"SECRET",[401,764,682],{"class":485},[362,766,767,769],{},[388,768,756],{}," 會同時檢查 signature 與過期時間。如果驗證失敗，會直接拋出錯誤。這就是伺服器端保護 API 的核心機制。",[369,771],{},[372,773,775],{"id":774},"jwt-適合哪些應用場景","JWT 適合哪些應用場景？",[362,777,778],{},"JWT 特別常見於 SPA（例如 React、Vue、Nuxt）與 mobile app。由於前後端分離架構中，API 通常是獨立存在的，使用 JWT 可以讓 API server 保持無狀態，減少對 session store 的依賴。",[362,780,781],{},"在 microservices 架構中，JWT 也非常實用。因為每個服務都可以自行驗證 token，而不需要集中式 session 管理。這讓系統更容易擴展，也更適合雲端環境。",[369,783],{},[372,785,787],{"id":786},"jwt-的本質與安全觀念","JWT 的本質與安全觀念",[362,789,790],{},"請牢記一句話：",[792,793,794],"blockquote",{},[362,795,796],{},[420,797,798],{},"JWT 是被 secret key 簽名的身份資料。",[362,800,801],{},"伺服器真正信任的不是 payload，而是 signature。只要 secret key 沒有洩漏，攻擊者就無法偽造合法的 token。",[362,803,804],{},"然而，JWT 並不是萬能解法。它仍然需要搭配 HTTPS、防止 XSS、妥善管理 secret key，以及考慮 token 失效與刷新機制（refresh token）等設計。",[369,806],{},[372,808,809],{"id":809},"結語",[362,811,812],{},"JWT 驗證其實非常單純：伺服器簽發 token，客戶端保存 token，之後的每一次請求都帶上它，伺服器再驗證它。只要你理解「簽名」與「無狀態」這兩個核心概念，就真正掌握了 JWT authentication 的本質。",[362,814,815],{},"當你在 Nuxt 或其他前端框架中實作登入系統時，只要記得：HTTP 不會記得使用者，而 JWT 是讓伺服器重新辨認使用者的一種方式。",[817,818,819],"style",{},"html pre.shiki code .s4JwU, html code.shiki .s4JwU{--shiki-default:#85E89D}html pre.shiki code .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}html pre.shiki code .s95oV, html code.shiki .s95oV{--shiki-default:#E1E4E8}html pre.shiki code .sDLfK, html code.shiki .sDLfK{--shiki-default:#79B8FF}html pre.shiki code .snl16, html code.shiki .snl16{--shiki-default:#F97583}",{"title":386,"searchDepth":489,"depth":489,"links":821},[822,823,824,825,826,827,828,829],{"id":374,"depth":489,"text":375},{"id":447,"depth":489,"text":448},{"id":576,"depth":489,"text":577},{"id":617,"depth":489,"text":618},{"id":640,"depth":489,"text":641},{"id":774,"depth":489,"text":775},{"id":786,"depth":489,"text":787},{"id":809,"depth":489,"text":809},"深入理解 JWT（JSON Web Token）的運作原理與完整驗證流程，學會如何在 Node.js 與 SPA 架構中實作無狀態身份驗證。","md",null,{"tags":834,"category":203,"date":840},[835,836,837,838,839],"jwt","authentication","nodejs","security","api","2026-02-13",true,{"title":323,"description":830},"zDsAEPZNkZiziqMmlpugLL9oc9p33ANSOGF0_vNOB3U",[845,847],{"title":319,"path":320,"stem":321,"description":846,"children":-1},"從 HTTP 無狀態特性開始，深入理解 Cookie 與 Session 的分工、登入流程與 Node.js 實作範例，建立完整的使用者驗證心智模型。",{"title":327,"path":328,"stem":329,"description":848,"children":-1},"不用先懂 JWT，也能理解 secret key 簽名在做什麼。帶你從問題出發，掌握資料完整性與驗證機制的核心原理。",1776690848431]