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 ...
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 ...
Pre-filtering vs. Post-filtering
關於訂餐LEFT JOIN 事後過濾📜 SQL 執行順序LEFT JOIN 前置過濾INNER JOINsummary午休前的辦公室接近午休時間。Team leader 桌子一拍:「各位肥宅!麥當勞開團囉!」
Jacky 抬頭:「請客嗎?」Leader 停了一秒:「呃…好,可以。」
話才剛落音,幾個原本裝忙的同事像被觸發開關似地站起來,開始熱烈點餐:
「大薯 + 可樂,搭配麥脆雞腿堡。」
「大麥克加一份生菜,再配玉米濃湯。」
「精緻牛排。」
「鱈魚堡微糖少冰,搭配雪碧。」
………………
Leader 看著訊息流越滾越誇張,只能扶額:「靠…我是不是講太大聲了?剛剛是不是還混進奇怪的東西?」
外送到後,大家開始大快朵頤,享受難得的免費午餐,而辦公室的一角,Allen 才剛把耳機拿下,看著眾人吃得開心,因為工作太專注,他完全錯過開團訊息
另一邊,也有同事沒發聲,只因為不喜歡炸物,於是默默提著自己的 Subway 回到座位
以資料表的角度來看,這裡會有兩張表
Employee(員工資料)
Order(訂餐資料)
現在我們想查的是哪些員工有參與「活動」(例如平常都跟團),但沒有參與 ...
ReadUncommitted and SnapShot
板著一張臉IsolationLevelIsolationLevel = SnapShotSnapShot - 一步步來資料庫設定使用 TempDB 儲存「行版本(Row Versions)」寫入衝突(Update Conflict)什麼情況下用 SNAPSHOT 最適合?什麼情況下用 SNAPSHOT 不適合?一個真實的 DirtyRead 案件結語
他的聲音低沉,又總是板著一張臉,走在路上連大人都會不自覺讓開,更別說孩子了。小孩一靠近他,他眉頭一皺,小朋友就嚇得跑掉。
久而久之,村裡流傳的故事越變越誇張,有人說他脾氣壞、有人說他討厭小孩、有人說他從不關心別人這些話像一堆未經查證的資訊在村裡亂流,就像大家用著 ReadUncommitted 的方式在認識他,還沒看清就急著下結論。
一個人的真心,不是聽來的,而是他在困境裡做出的選擇,謠言說的都是 Uncommitted 的版本,唯有親眼看見的 Snapshot,才是真實的他
在同一段交易裡,你接受看到「哪一種樣子的世界」?
在多人同時查資料、改資料的世界裡,不可能做到「既快、又完全正確、又不互相干擾」。資料庫永遠在做取捨,而 Isol ...
Open Redirect
不安全的轉導(Open Redirect)白名單(Whitelist)驗證Relative Path加簽驗證(Signature)限制參數長度與格式— 防止繞過技巧增加跳轉提示頁(中介頁)攻擊手法summary🔆🔆 「🇯🇵 日本電商客服 月薪 8 萬|包吃住|合法公司詳情私我」 🔆🔆
他心想,「哇,日本耶!而且朋友的朋友介紹,應該很穩吧。」
於是他私訊、面試、簽約,一切流程超順,順到像自動登入了光明人生。後來對方說了:「先飛曼谷,再有人帶你過去。」
他當下沒有多想,就像看到網址是 https://trusted-company.com,沒去看後面的參數
下飛機後,接他的人說:「等等換一台車。」
換著換著,風景從市區 → 郊外 → 鐵門 → ❌ 404:你以為的人生不在這裡
Open Redirect 本質是,「把跳轉控制權交給使用者,卻沒有驗證對方要帶你去哪裡」,這會讓原本可信的網站,變成幫攻擊者背書的跳板
https://nice.com/redirect?target=https://phishing-site.com
因此,若應用程式提供 redir ...













