shopping-cart-2
為什麼需要 AntiForgeryTokenDataCache vs CoreCache清除快取策略(CleanCacheService)整體架構總結
CSRF(Cross-Site Request Forgery,跨站請求偽造) 是一種攻擊手法:攻擊者讓已登入的使用者,在不知情的狀況下,對目標網站送出偽造的請求。
12345① 使用者登入了購物網站,瀏覽器已有登入 Cookie② 使用者同時開著惡意網頁(例如被誘騙點開的廣告)③ 惡意網頁偷偷對購物網站發出 POST /api/checkout/create 請求④ 瀏覽器自動帶上 Cookie,購物網站以為是本人操作⑤ 攻擊者成功替使用者結帳,或清空購物車
請求必須帶著一個只有真正前端頁面才拿得到的一次性 Token。惡意網頁無法預先取得這個 Token,因此偽造請求會被擋下
Redis Key 設計1234Core:AntiForgeryToken-20230821:{shopId}:{token}範例:Core:AntiForgeryToken-20230821:10416:f47ac ...
shopping-cart
三層 Key(shopId / memberId / uniqueKey)Transformer只更新特定 Redis FieldCheckout UniqueKey個資兩次存取(存原始、傳遮罩)PartialCheckoutData TTL 由設定檔控制PersonalDataMask TTL 60 分鐘只讀 ShoppingDateTimeUtc 判斷過期summmary
第一層:shopIdKey 格式: Core:PartialCheckoutData-20230410:{shopId}:...
防護:多租戶(Multi-tenant)
91APP 服務數千個商店,每個商店共用同一套程式和同一個 Redis。若沒有 shopId 隔離,商店 A(ShopId=100)的結帳資料,理論上可以被商店 B(ShopId=200)的程式讀到。
第二層:memberIdKey 格式: Core:PartialCheckoutData-20230410:{shopId}:{memberId}:...
防護:跨用戶資料洩漏
同一個商店的不同會員,結帳資料要絕對隔離。會員 A(Member ...
Time To Live
Cache Time這筆資料變動快不快資料舊一點能不能接受用「更新頻率 + 可接受延遲」一起決定 TTL「靠時間過期」還是「事件觸發失效」進行中活動快取大量 key 同時失效監控回頭調整,不用一次定生死TTL 的本質是拿「資料新鮮度」去交換「系統速度、成本和穩定性」
第一步先看資料本身的更新頻率
商品名稱、分類這種通常很少改
庫存、價格、優惠活動可能常常變
使用者個人首頁資料可能又跟行為密切相關
TTL 本質上是根據資料變動速度來決定壽命。如果資料一天才改一次,你卻設 5 秒,快取幾乎沒價值,還會一直回源查資料庫。反過來,如果資料每分鐘都會變,你卻設 1 小時,使用者看到舊資料的機率就很高
不是所有資料都需要絕對即時。例如
最新新聞列表晚 30 秒更新,通常很多人能接受
商品庫存晚 10 分鐘更新,可能就會出事
交易餘額、付款狀態,如果延遲顯示就很危險
這一步重要,因為 TTL 設計真正要回答的是這份資料最久可以舊到什麼程度,業務還能接受。如果不先定義容忍度,你就會只靠感覺亂設 TTL。最後不是快取命中率太低,就是資料過期太久,兩邊都不討好。
資料更新很少,容忍延遲高 → T ...
Redis 的存取控制(Authentication 與 ACL)
存取控制情境 A:故意做一個「未設密碼、可直接連線」的 Redis情境 B:設 requirepass情境 C:Redis 6+ ACL(ACL USERS / ACL GETUSER default)結果整理
Redis 的權限設定,本質是在「界定誰可以對資料做哪些事」,避免任何能連線的人都變成系統管理員,目的是為了防止「連線成功 = 全權控制」這種過於危險的設計被直接暴露在現實世界,尤其 Redis 常用於儲存重要的暫存資料、session、token 等,一旦外洩後果嚴重,在預設情況下,啟用的是 6379 port,若未設定密碼(requirepass)或防火牆規則,任何人只要知道伺服器 IP,就可以直接連線存取資料存取控制(Access Control)
最小授權原則(Least Privilege)被忽略:沒有設定 ACL 或密碼等限制,導致所有人都能以最高權限操作 Redis
資料與系統間的橋樑風險:攻擊者一旦能控制 Redis,就能利用 Redis 的指令把惡意內容寫進 .ssh 資料夾,進而用 SSH 登入伺服器,取得完整控制權
這個階段會綁定 0.0.0. ...
LoggerFactory
Reference
服務(Service)直接注入 ILogger 來使用在 Program.cs 使用 CreateLogger()CategoryFactory Pattern為什麼不直接 new Loggersummary表層1234567891011121314public class OrderService{ private readonly ILogger<OrderService> _logger; public OrderService(ILogger<OrderService> logger) { _logger = logger; } public void PlaceOrder() { _logger.LogInformation("Place order"); }}
🕒 T0:應用程式啟動時1var builder = WebApplication.CreateBuilder(ar ...
Cammand
指令觀察 container 狀態觀察 Image拉取 api server image將 server 在本地跑起來
Docker 把「你要操作的東西」放在指令正中間,為了讓人一眼就知道「你在動誰、要對它做什麼」
docker:告訴系統你要使用 Docker 這套工具,就像進入一個控制台,後面的內容都在 Docker 的語境裡
container / image / volume / network(對象):明確指定你要操作的資源種類先講「我要動的是容器?映像檔?還是網路?」
run / ps / rm / build(指令):對這個對象要做的行為,在對象已經清楚的前提下,再說你要做什麼動作
參數:補充條件與細節,像是名稱、port、detach、env,這些都是「怎麼做」的細節
工具 → 目標 → 動作 → 細節
例如
1docker container rm my-nginx
用 docker對 container做 rm(刪除)目標是 my-nginx
這句話幾乎可以直接唸成白話,不需要先背語法規則! Docke ...
Redis - 分散式架構(Sharding)
分散式架構Redis 分散式架構(Sharding)Hot Key 為什麼會讓 Sharding 失效summary當整個城市只有一條主幹道,不管你是上班、回家、買菜,全部擠在同一條路
Sharding 是什麼?他直接多鋪幾條平行道路,每條路有自己的流量上限、有自己的責任區,目的就是不要讓任何一條路成為整座城市的瓶頸,Redis Cluster 會把資料自動 sharding 到多個節點上,讓資料集和負載可以水平擴展
分散式的 Redis 就是 Sharding 的概念,Sharding 的本質是為了讓「單台 Redis 永遠只處理自己撐得住的資料量」,不同的 Key/Value 會放到不同的 Redis 機器上,由系統(Redis Cluster)用「Hash」的方式計算放在哪裡
資料量與流量逐漸成長過程中,若把所有 key 都丟在同一台,記憶體、單執行緒會被撐滿,因此大流量站台通常架構上會搭配 Sharding ,讓每台 Redis 只負責自己那一部分 key,不共享資料、不互相鎖,Client 或 Redis Cluster 幫你處理 routing,你只管用 key ...
Asynchronous - 第十五章:Host Task
Task-based Asynchronous Pattern(TAP)中的 Hot Task 行為如果真的「不想馬上開始」會怎樣為什麼 new Task(...) 不會自動執行summary
TAP 的核心不是「延遲執行」,而是「把等待時間變成可並行」,async 方法在呼叫的那一刻就開始執行,是因為非同步的價值在於「提早把 I/O 交出去跑」,而不是等你 await 才開始,我們用一個例子來觀察
Step 1:呼叫 DownloadFileAsync(url)1getContentTasks.Add(DownloadFileAsync(url));
這一步不是僅是宣告任務,而是真的執行這個方法
Step 2:進入 DownloadFileAsync 方法本體1234async Task DownloadFileAsync(string url){ await httpClient.GetAsync(url);}
方法一進來就跑,直到遇到第一個 await
Step 3:遇到 HttpClient.GetAsync()這是一個 I/O ...
Dockerfile
Dcokerfile工作流程Dockerfile 實作Dockerfile 實作Dockerfile 是「怎麼做」的規則,而 Image 是「照規則做完後」的結果;一個負責描述過程,一個負責被拿來用,Dockerfile 本質上就是一份「把環境準備流程寫成程式碼」的說明書,讓電腦每次都用一模一樣的步驟,生出一模一樣的執行環境
假設寫了一個後端 API,你的電腦可以跑,而同事電腦版本不合,可能是因為環境完全不同,如果沒有 Dockerfile,只能用嘴巴或 README 描述:「先裝這個、再裝那個、版本要對喔」,而有 Dockerfile,等於是直接說「照這份 Dockerfile build,就一定能跑。」
撰寫 Dockerfile
先寫 Dockerfile ,其中裡面要寫清楚從哪個基底環境開始、要裝哪些套件、程式放哪、容器啟動要幹嘛
設定工作目錄,決定之後所有指令是在容器裡的哪個資料夾執行
準備需要的檔案,把程式碼、設定檔複製進容器
安裝依賴套件,用指令把程式需要的套件一次裝好
設定啟動方式,告訴 Docker 這個環境「跑起來」時,要執行哪個指令
👉 Docker 會照 ...
Image Layer
Image Layer唯獨層、可寫層實驗形成新的 layer驗證「Docker 不會重複存兩份 node:20(layer 共用)」summary30 歲的那天我睡著了,隔天醒來,用「30 歲為止的 Image」,啟動了一個新的 Container,這個 Image 是過去經驗的凍結結果,你沒辦法在 Container 裡直接改 Image,把某一層人生經驗 hot fix,你只能用現在這份 Image 決定今天要跑出怎樣的一個實例
Image 就是那一疊已經整理好、不能再亂改的「環境變更記錄」,他是一份「如何把環境一步步疊起來的凍結結果」,而不是一個正在運作的東西,這些變更記錄加起來,組成一個「可執行的環境起點」
比較一下就是
Image「我『應該長怎樣』的說明書 + 已經準備好的環境層」Container「照著這份說明書,真的跑起來的一次實例」
Image 結構是多個 layer,每一層都是一次檔案系統的變更(新增 / 修改 / 刪除),最終組合成一個完整檔案系統視圖,他可以被重複掛載、可以被重複使用,用來作為 container 的起始基準
確認 Doc ...









