[{"data":1,"prerenderedAt":939},["ShallowReactive",2],{"navigation_docs":3,"-web-dev-security-secret-key-signing":352,"-web-dev-security-secret-key-signing-surround":934},[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":327,"body":354,"description":920,"extension":921,"links":922,"meta":923,"navigation":931,"path":328,"seo":932,"stem":329,"__hash__":933},"docs/web_dev/security/secret-key-signing.md",{"type":355,"value":356,"toc":902},"minimark",[357,361,365,374,377,415,418,425,428,433,436,443,450,453,464,486,496,498,501,504,509,530,534,548,552,559,561,565,572,581,584,593,607,613,615,619,625,639,645,647,650,653,664,667,669,673,683,686,757,767,774,776,780,787,790,819,822,841,848,850,853,859,862,864,867,873,876,895,898],[358,359,327],"h1",{"id":360},"secret-key-簽名是什麼從零理解資料簽名的本質",[362,363,364],"p",{},"在 Web 開發中，我們經常會把資料交給使用者，例如登入後的身分資訊、權限資訊、或某些狀態資料。但有一個根本問題必須先釐清：",[366,367,368],"blockquote",{},[362,369,370],{},[371,372,373],"strong",{},"如果資料被使用者改掉，伺服器要怎麼知道？",[362,375,376],{},"假設 Server 傳給 Client 一段資料：",[378,379,384],"pre",{"className":380,"code":381,"language":382,"meta":383,"style":383},"language-json shiki shiki-themes github-dark","{\n  \"userId\": 42\n}\n","json","",[385,386,387,396,409],"code",{"__ignoreMap":383},[388,389,392],"span",{"class":390,"line":391},"line",1,[388,393,395],{"class":394},"s95oV","{\n",[388,397,399,403,406],{"class":390,"line":398},2,[388,400,402],{"class":401},"sDLfK","  \"userId\"",[388,404,405],{"class":394},": ",[388,407,408],{"class":401},"42\n",[388,410,412],{"class":390,"line":411},3,[388,413,414],{"class":394},"}\n",[362,416,417],{},"Server 的要求其實很單純：你可以讀這份資料，但不能修改它。",[362,419,420,421,424],{},"然而，HTTP 是一種可被攔截與修改的通訊形式。只要資料回到 Client 端，理論上都可能被竄改。那麼 Server 要如何判斷這份資料是否還是「原本那一份」？這個問題的答案，就是「",[371,422,423],{},"簽名（Signing）","」。",[426,427],"hr",{},[429,430,432],"h2",{"id":431},"簽名到底在做什麼","簽名到底在做什麼？",[362,434,435],{},"簽名的核心概念非常單純：",[366,437,438],{},[362,439,440],{},[371,441,442],{},"用「資料 + 只有 Server 知道的 Secret Key」產生一段不可偽造的指紋。",[362,444,445,446,449],{},"這段指紋通常是透過一種單向運算產生，例如雜湊函式（Hash Function）。常見的做法是使用 ",[371,447,448],{},"HMAC","（Hash-based Message Authentication Code）。",[362,451,452],{},"概念上可以寫成：",[378,454,458],{"className":455,"code":456,"language":457,"meta":383,"style":383},"language-ini shiki shiki-themes github-dark","signature = hash(data + secret)\n","ini",[385,459,460],{"__ignoreMap":383},[388,461,462],{"class":390,"line":391},[388,463,456],{},[465,466,467,474,480],"ul",{},[468,469,470,473],"li",{},[371,471,472],{},"data","：你要保護的資料。",[468,475,476,479],{},[371,477,478],{},"secret","：只有 Server 知道的密鑰。",[468,481,482,485],{},[371,483,484],{},"hash","：單向運算（無法反推出原始資料）。",[362,487,488,489,492,493,424],{},"最後會得到一段固定長度的字串，例如：",[385,490,491],{},"a8f9c2d1e4b7...","。這段字串，就是「",[371,494,495],{},"簽名",[426,497],{},[429,499,500],{"id":500},"簽名的完整流程",[362,502,503],{},"我們用一個簡化版本的流程來看整個運作方式。",[505,506,508],"h3",{"id":507},"step-1server-建立資料","Step 1：Server 建立資料",[378,510,512],{"className":380,"code":511,"language":382,"meta":383,"style":383},"data = { \"userId\": 42 }\n",[385,513,514],{"__ignoreMap":383},[388,515,516,519,522,524,527],{"class":390,"line":391},[388,517,518],{"class":394},"data = { ",[388,520,521],{"class":401},"\"userId\"",[388,523,405],{"class":394},[388,525,526],{"class":401},"42",[388,528,529],{"class":394}," }\n",[505,531,533],{"id":532},"step-2server-用-secret-產生簽名","Step 2：Server 用 Secret 產生簽名",[378,535,537],{"className":455,"code":536,"language":457,"meta":383,"style":383},"secret = \"my-secret\"\nsignature = hash(data + secret)\n",[385,538,539,544],{"__ignoreMap":383},[388,540,541],{"class":390,"line":391},[388,542,543],{},"secret = \"my-secret\"\n",[388,545,546],{"class":390,"line":398},[388,547,456],{},[505,549,551],{"id":550},"step-3server-傳送資料-簽名","Step 3：Server 傳送資料 + 簽名",[362,553,554,555,558],{},"Client 最終會拿到：",[385,556,557],{},"{ \"userId\": 42 } + signature","。此時 Client 可以看到資料內容，但無法偽造簽名。",[426,560],{},[429,562,564],{"id":563},"驗證機制如何運作","驗證機制如何運作？",[362,566,567,568,571],{},"當 Client 把資料送回 Server 時，Server 會做一件事：",[371,569,570],{},"重新計算簽名","。",[378,573,575],{"className":455,"code":574,"language":457,"meta":383,"style":383},"signature2 = hash(data + secret)\n",[385,576,577],{"__ignoreMap":383},[388,578,579],{"class":390,"line":391},[388,580,574],{},[362,582,583],{},"然後比較：",[378,585,587],{"className":455,"code":586,"language":457,"meta":383,"style":383},"signature2 === 原本的 signature ?\n",[385,588,589],{"__ignoreMap":383},[388,590,591],{"class":390,"line":391},[388,592,586],{},[465,594,595,601],{},[468,596,597,600],{},[371,598,599],{},"如果一致","：代表資料沒有被修改。",[468,602,603,606],{},[371,604,605],{},"如果不一致","：代表資料被竄改。",[362,608,609,610,424],{},"這整個過程稱為「",[371,611,612],{},"驗證簽名（Verification）",[426,614],{},[429,616,618],{"id":617},"為什麼攻擊者無法偽造","為什麼攻擊者無法偽造？",[362,620,621,622,571],{},"關鍵就在於 ",[371,623,624],{},"Secret Key",[362,626,627,628,631,632,635,636,571],{},"假設攻擊者把 ",[385,629,630],{},"userId: 42"," 改成 ",[385,633,634],{},"userId: 1","。他想重新產生簽名，但他不知道 Secret，他只能算：",[385,637,638],{},"hash(data + ???)",[362,640,641,642,424],{},"因為缺少 Secret，無法得到正確的簽名。Server 一驗證就會發現不一致。這種機制確保了資料的「",[371,643,644],{},"完整性（Integrity）",[426,646],{},[429,648,649],{"id":649},"簽名不是加密",[362,651,652],{},"很多人會混淆「加密（Encryption）」與「簽名（Signing）」：",[465,654,655,658],{},[468,656,657],{},"簽名的目的不是為了隱藏資料或讓資料看不懂。",[468,659,660,661,571],{},"簽名的目的是為了",[371,662,663],{},"確保資料沒有被修改",[362,665,666],{},"也就是說，簽名解決的是「完整性」，不是「機密性」。資料本身可以是公開的，但只要簽名正確，Server 就能信任這份資料。",[426,668],{},[429,670,672],{"id":671},"jwt-裡的-secret-key-簽名","JWT 裡的 Secret Key 簽名",[362,674,675,676,679,680,571],{},"在 ",[371,677,678],{},"JWT（JSON Web Token）"," 中，簽名機制正是使用這個原理。JWT 的結構是：",[385,681,682],{},"header.payload.signature",[362,684,685],{},"前兩段（Header + Payload）是資料本身。第三段（Signature）是這樣產生的：",[378,687,691],{"className":688,"code":689,"language":690,"meta":383,"style":383},"language-bash shiki shiki-themes github-dark","signature = HMACSHA256( \n  base64(header) + \".\" + base64(payload), \n  SECRET_KEY \n)\n","bash",[385,692,693,709,744,751],{"__ignoreMap":383},[388,694,695,699,703,706],{"class":390,"line":391},[388,696,698],{"class":697},"svObZ","signature",[388,700,702],{"class":701},"sU2Wk"," =",[388,704,705],{"class":701}," HMACSHA256",[388,707,708],{"class":394},"( \n",[388,710,711,714,717,720,723,726,729,732,735,738,741],{"class":390,"line":398},[388,712,713],{"class":697},"  base64(header",[388,715,716],{"class":394},") ",[388,718,719],{"class":701},"+",[388,721,722],{"class":701}," \".\"",[388,724,725],{"class":701}," +",[388,727,728],{"class":701}," base64",[388,730,731],{"class":394},"(",[388,733,734],{"class":697},"payload",[388,736,737],{"class":394},")",[388,739,740],{"class":701},",",[388,742,743],{"class":394}," \n",[388,745,746,749],{"class":390,"line":411},[388,747,748],{"class":697},"  SECRET_KEY",[388,750,743],{"class":394},[388,752,754],{"class":390,"line":753},4,[388,755,756],{"class":394},")\n",[362,758,759,760,763,764,571],{},"常見演算法就是 ",[371,761,762],{},"HMAC-SHA256","。JWT 的安全性並不是來自 Payload 本身（它是 Base64 編碼，任何人都能解碼），而是來自 ",[371,765,766],{},"Signature",[366,768,769],{},[362,770,771],{},[371,772,773],{},"Server 不相信 Payload，而是相信 Signature。",[426,775],{},[429,777,779],{"id":778},"nodejs-實作範例","Node.js 實作範例",[362,781,782,783,786],{},"使用 ",[385,784,785],{},"jsonwebtoken"," 套件時：",[505,788,789],{"id":789},"建立簽名",[378,791,795],{"className":792,"code":793,"language":794,"meta":383,"style":383},"language-js shiki shiki-themes github-dark","jwt.sign({ userId: 42 }, SECRET);\n","js",[385,796,797],{"__ignoreMap":383},[388,798,799,802,805,808,810,813,816],{"class":390,"line":391},[388,800,801],{"class":394},"jwt.",[388,803,804],{"class":697},"sign",[388,806,807],{"class":394},"({ userId: ",[388,809,526],{"class":401},[388,811,812],{"class":394}," }, ",[388,814,815],{"class":401},"SECRET",[388,817,818],{"class":394},");\n",[505,820,821],{"id":821},"驗證簽名",[378,823,825],{"className":792,"code":824,"language":794,"meta":383,"style":383},"jwt.verify(token, SECRET);\n",[385,826,827],{"__ignoreMap":383},[388,828,829,831,834,837,839],{"class":390,"line":391},[388,830,801],{"class":394},[388,832,833],{"class":697},"verify",[388,835,836],{"class":394},"(token, ",[388,838,815],{"class":401},[388,840,818],{"class":394},[362,842,843,844,847],{},"這兩行背後的本質，就是 ",[385,845,846],{},"hash(data + secret)"," 的計算與比對。",[426,849],{},[429,851,852],{"id":852},"一個直覺的心智模型",[362,854,855,856],{},"你可以把 Secret Key 簽名想成：",[371,857,858],{},"Server 用一個只有自己知道的印章，在資料上蓋章。",[362,860,861],{},"任何人都可以看到資料內容，但只有 Server 能蓋出真正的印章。如果資料被動過，印章就對不上。",[426,863],{},[429,865,866],{"id":866},"最重要的總結",[362,868,869,870],{},"Secret Key 簽名的本質只有一件事：",[371,871,872],{},"用 Secret 產生不可偽造的資料指紋，讓 Server 能驗證資料是否被修改。",[362,874,875],{},"在 JWT 中：",[465,877,878,884,889],{},[468,879,880,883],{},[371,881,882],{},"Header + Payload"," 是資料。",[468,885,886,888],{},[371,887,766],{}," 是指紋。",[468,890,891,894],{},[371,892,893],{},"Secret"," 是印章。",[362,896,897],{},"只要理解這三個角色，你就真正理解了「簽名到底在做什麼」。",[899,900,901],"style",{},"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 .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 .svObZ, html code.shiki .svObZ{--shiki-default:#B392F0}html pre.shiki code .sU2Wk, html code.shiki .sU2Wk{--shiki-default:#9ECBFF}",{"title":383,"searchDepth":398,"depth":398,"links":903},[904,905,910,911,912,913,914,918,919],{"id":431,"depth":398,"text":432},{"id":500,"depth":398,"text":500,"children":906},[907,908,909],{"id":507,"depth":411,"text":508},{"id":532,"depth":411,"text":533},{"id":550,"depth":411,"text":551},{"id":563,"depth":398,"text":564},{"id":617,"depth":398,"text":618},{"id":649,"depth":398,"text":649},{"id":671,"depth":398,"text":672},{"id":778,"depth":398,"text":779,"children":915},[916,917],{"id":789,"depth":411,"text":789},{"id":821,"depth":411,"text":821},{"id":852,"depth":398,"text":852},{"id":866,"depth":398,"text":866},"不用先懂 JWT，也能理解 secret key 簽名在做什麼。帶你從問題出發，掌握資料完整性與驗證機制的核心原理。","md",null,{"tags":924,"category":203,"date":930},[925,926,927,928,929],"security","jwt","hmac","backend","web","2026-02-13",true,{"title":327,"description":920},"4wrqvAwiBCXhFbFhhKWGyXG4Xza7TWzdF4xzmYICKtM",[935,937],{"title":323,"path":324,"stem":325,"description":936,"children":-1},"深入理解 JWT（JSON Web Token）的運作原理與完整驗證流程，學會如何在 Node.js 與 SPA 架構中實作無狀態身份驗證。",{"title":331,"path":332,"stem":333,"description":938,"children":-1},"深入介紹 SSH（Secure Shell）的用途與功能，理解它如何成為現代伺服器管理、遠端開發與自動化部署中不可或缺的安全基礎。",1776690848512]