# API 方法參數設計:採用約定型別  在 `Bee.NET` 架構中,API 採用「約定型別」(Convention-based Types)與 `$type` 型別標記模式,達成模組化設計與型別安全,同時兼顧彈性與防禦性。本文說明如何設計 API 方法參數與安全的 JSON-RPC 反序列化策略,打造可維護、可擴充且具高安全性的企業系統架構。 --- ## 🧩 設計核心原則 - 每個 API 方法對應一個 `Args` 類別(輸入)與一個 `Result` 類別(輸出) - 所有輸入參數封裝為類別,以支援版本向前相容(可加欄位) - 僅允許反序列化指定命名空間(透過白名單)內的型別 - 所有 JSON 傳輸物件需包含 `$type` 欄位,明確指明型別 ```csharp /// <summary> /// 登入系統。 /// </summary> public LoginResult Login(LoginArgs args) { } /// <summary> /// 登入系統的傳入引數。 /// </summary> public class LoginArgs { public string UserId { get; set; } public string Password { get; set; } public string Language { get; set; } = "zh-TW"; } /// <summary> /// 登入系統的傳出結果。 /// </summary> public class LoginResult { public Guid AccessToken { get; set; } public DateTime ExpiredAt { get; set; } } ``` --- ## ✅ 採用約定型別的好處 | 優點 | 說明 | |----------------|------| | 向前相容 | 可新增屬性並設定預設值,不影響舊版相容性 | | 型別安全 | 強型別設計,降低傳錯資料或誤用風險 | | 流程統一 | 序列化、驗證、日誌與加解密等可共用基礎設計 | | 易於測試與維護 | 結構清晰,方便進行模組化測試與維護 | | 文件自動化 | 可結合 Swagger 或 DocFX 自動生成 API 文件 | --- ## ❌ 可能的挑戰 | 挑戰項目 | 說明 | |----------------|------| | 學習曲線 | 需理解命名慣例與封裝邏輯 | | 類型數量增加 | 每個方法需額外定義 Args/Result,命名與管理需規範 | | 不適合極簡操作 | 若僅需傳遞單一欄位,封裝類別略顯冗長 | | 反序列化風險 | 必須控管允許反序列化的型別來源,避免安全漏洞 | --- ## ✅ 型別白名單機制與安全策略 為防止反序列化攻擊(Deserialization Attack),要求所有透過 `$type` 傳遞的型別資訊,皆必須來自受信任的命名空間。這項機制確保系統只會反序列化已知且安全的資料物件(DTO),有效阻止任意程式邏輯被觸發。 ### 限制允許反序列化的命名空間 系統僅允許 `$type` 對應的型別來自預設或設定檔指定的命名空間: ```xml <Settings> <AllowedTypeNamespaces> <Namespace>Custom.Define</Namespace> </AllowedTypeNamespaces> </Settings> ``` ### 預設安全命名空間 預設自動允許以下命名空間,不須額外設定: - `Bee.Base` - `Bee.Define` ```csharp AllowedTypeNamespaces = new List<string> { "Bee.Base", "Bee.Define", // 來自設定檔的其他命名空間 }; ``` 這種設計不僅簡化部署流程,也避免遺漏必要命名空間。 --- ### ✅ 型別反序列化安全原則 僅允許來自信任命名空間的純資料物件(DTO)進行反序列化,所有 `$type` 指定的型別皆必須符合以下條件: - 所有 DTO 型別皆為預先定義的資料物件,僅包含屬性,無任何執行邏輯 - 執行期間不會觸發任何自動化方法或反射邏輯 - 僅允許來自指定命名空間(如 `Bee.Define`, `Custom.Define`)的型別 - 在防禦攻擊的同時,保有 RPC 設計的彈性與可擴充性 --- ## 📌 小結 `Bee.NET` 採用 `$type` 型別標記與命名空間白名單設計,在兼顧彈性與維護性的前提下,有效防堵反序列化攻擊,是建構高安全性 API 架構的關鍵設計策略。 --- **📢 歡迎轉載,請註明出處** **📬 歡迎追蹤我的技術筆記與實戰經驗分享** [Facebook](https://www.facebook.com/profile.php?id=61574839666569) | [HackMD](https://hackmd.io/@jeff377) | [GitHub](https://github.com/jeff377) | [NuGet](https://www.nuget.org/profiles/jeff377)
×
Sign in
Email
Password
Forgot password
or
Sign in via Google
Sign in via Facebook
Sign in via X(Twitter)
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
Continue with a different method
New to HackMD?
Sign up
By signing in, you agree to our
terms of service
.