ASP.NET沒有魔法——ASP.NET MVC使用Oauth2.0實現身份驗證

来源:http://www.cnblogs.com/selimsong/archive/2017/12/18/8037717.html
-Advertisement-
Play Games

隨著軟體的不斷發展,出現了更多的身份驗證使用場景,除了典型的伺服器與客戶端之間的身份驗證外還有,如服務與服務之間的(如微服務架構)、伺服器與多種客戶端的(如PC、移動、Web等),甚至還有需要以服務的形式開放給第三方的,身份驗證這一功能已經演化為一個服務,很多大型應用中都有自己的身份驗證伺服器甚至集 ...


  隨著軟體的不斷發展,出現了更多的身份驗證使用場景,除了典型的伺服器與客戶端之間的身份驗證外還有,如服務與服務之間的(如微服務架構)、伺服器與多種客戶端的(如PC、移動、Web等),甚至還有需要以服務的形式開放給第三方的,身份驗證這一功能已經演化為一個服務,很多大型應用中都有自己的身份驗證伺服器甚至集群,所以普通的身份驗證方式已經不能滿足需求。

  在.Net領域中也有一些開源的身份驗證伺服器組件,如IdentityServer(http://identityserver.io/),但是這些組件對於一些規模較小的項目來說可能會感覺到比較龐大,增加了學習和維護成本,所以本章將對OAuth以及如何使用OAuth實現身份驗證模式進行介紹。
  本章的主要內容有:

  ● OAuth2.0簡介
  ● 在.Net中使用OAuth實現基於授權碼模式的身份驗證
  ● 實現基於Access Token的身份驗證
  ● 加入Refresh Token支持
  ● 實現通過用戶密碼模式獲取Access Token
  ● 實現客戶端模式獲取Access Token
  ● 關於.Net中OAuth相關令牌的加密說明

  註:本章內容源碼下載:https://files.cnblogs.com/files/selimsong/OAuth2Demo.zip

OAuth2.0簡介

  在文章的開始的時候說過現代軟體應用的身份驗證場景越來越豐富,下圖是現代應用程式的一個通信圖,它描述了常見的“客戶端”是如何與伺服器提供的服務通信的。

  

  該圖出自IdentityServer:https://identityserver4.readthedocs.io/en/release/intro/big_picture.html
  為了滿足這些場景人們制定了一套標準協議,這個協議就是OAuth(Open Authorization,開放授權)協議,OAuth能夠讓第三方應用程式去訪問受限制的HTTP服務。OAuth有兩個版本分別是1.0和2.0,但是由於1.0版本過於複雜所以1.0版本被2.0版本替換了,並且兩個版本是不相容的。
  接下來就對OAuth2.0相關的概念進行介紹:

1. OAuth2.0中的角色

  ● Resource Owner:資源擁有者,就是能夠訪問被限制資源的用戶(註:這裡的用戶是個泛指,它既可以是真實用戶也可以是服務程式)。
  ● Resource Server:資源宿主,能夠接受和處理,使用訪問令牌(access token)訪問受保護資源的請求(如提供API的伺服器)。
  ● Client:它泛指所有的第三方程式(無論是Web應用、桌面應用還是服務端應用),它通過資源擁有者以及它的授權來訪問受保護的資源。
  ● Authorization Server:用來對授權成功的客戶端發佈令牌以及對令牌的驗證授權。並對Client進行管理。

2.OAuth2.0的協議流程

  

  A. 第三方程式向資源擁有者(用戶)發送授權請求,這個過程既可以通過客戶端直接向用戶請求,也可以通過授權伺服器作為中介來完成請求。(註:對於授權請求這個概念相當於用戶登錄,應用程式可以直接顯示一個登錄頁面,也可以跳轉到驗證伺服器的統一登錄頁面
  B. 用戶將授權相關信息“提交”給第三方程式,在OAuth中有4種不同的許可權授予方式,每種方式需要的數據不同,如基於用戶密碼的授權方式就需要用戶名和密碼。
  C. 第三方程式將用戶的授權信息提交到授權伺服器,請求一個Access Token。
  D. 授權伺服器驗證完成用戶的授權信息後,將Access Token發放到第三方程式。
  E. 第三方程式攜帶Access Token訪問被保護的資源。
  F. 資源伺服器驗證Access Token有效後,將資源返回到第三方程式。

3. OAuth中的授權模式(即獲取Access Token的方式)

  ● Authorization Code(授權碼模式):該模式的核心是客戶端通過一個授權碼來向授權伺服器申請Access Token。是一種基於重定向的授權模式,授權伺服器作為用戶和第三方應用(Client)的中介,當用戶訪問第三方應用是,第三方應用跳轉到授權伺服器引導用戶完成身份驗證,生成Authorization Code並轉交到第三方應用,以便於第三方應用根據這個授權碼完成後續的Access Token獲取。
  ● Implicit(簡化模式):簡化模式是一種簡化的授權碼模式,授權碼模式在首次訪問第三方應用時跳轉到授權伺服器進行身份驗證返回授權碼,而簡化模式在跳轉到授權伺服器後直接返回Access Token,這種模式減少了獲取Access Token的請求次數。
  ● Resource Owner Password Credentials(用戶密碼模式):通過資源擁有者(用戶)的用戶名和密碼來直接獲取Access Token的一種方法,這種方法要求第三方應用(Client)是高度可信任的,並且其它授權方式不可用的情況下使用。
  ● Client Credentials(客戶端模式):該模式是通過第三方應用(Client)發送一個自己的憑證到授權伺服器獲得Access Token,這種模式的使用要求該Client已經被授權伺服器管理並限制其對被保護資源的訪問範圍。另外這種模式下Client應該就是一個資源擁有者(用戶),如微服務程式。

4. Access Token & Refresh Token

  這個很好理解,第三方應用通過Access Token去獲取受保護的資源,但是Access Token是存在有效期的,一旦過期就無法使用,為了避免Access Token過期後無法使用,所以加入了Refresh Token的概念,通過刷新的方式來完成Access Token的更新。

5. Client的註冊

  在OAuth2.0中,所有需要訪問受限資源的程式都視為第三方應用(Client),為了保證這個Client是安全的、可信任的,所以OAuth需要對Client進行管理。參考:https://tools.ietf.org/html/rfc6749#section-2

6. OAuth的終結點

  這裡終結點代表的是HTTP資源,在OAuth授權過程中需要使用到一些終結點的支持,如Authorization code(授權碼)的獲取,以及Access Token的獲取,終結點由授權伺服器提供。參考:https://tools.ietf.org/html/rfc6749#section-3

7. Access Token Type

  Access Token的類型是讓Client根據具體類型來使用Access Token完成對受保護資源的請求。
  OAuth2.0中有兩種類型分別是Bearer和Mac,它們體現方式如下:
   ● Bearer:

  

    ● Mac:

  

  參考:https://tools.ietf.org/html/rfc6750

在.Net中使用OAuth實現基於授權碼模式的身份驗證

  OAuth2.0是一個開放標準,既然是標準那麼就可以有實現,在.Net中微軟基於Owin實現了OAuth2.0協議,下麵就介紹如何在ASP.NET MVC程式中實現OAuth身份驗證。
  註:本例基於ASP.NET MVC預設帶身份驗證模板完成。

1. 組件安裝

  通過NuGet安裝Microsoft.Owin.Security.OAuth組件:

  

  註:從該組件的名稱可以看出,.Net對OAuth的實現實際上是基於Owin的,所以很多內容均使用Owin中相關的身份驗證概念,這些內容可參考本系列與身份驗證的文章。

2. 添加OAuth授權伺服器

  根據上面OAuth的介紹可知,授權伺服器是OAuth其中一個角色,該角色最主要的功能就是Access Token的發放以及授權,另外它還用於支持授權碼模式的授權碼發放以及Client的管理
  在Startup類型的Configuration方法中加入以下代碼,該代碼是為Owin中間件添加一個授權伺服器(註:該中間件是一個Owin的身份驗證中間件可參考《ASP.NET沒有魔法——ASP.NET Identity 的“多重”身份驗證)。

  

  其中OAuthAuthorizationServerOptions定義如下:

  

  上面的定義可以分為以下幾類:
  ● 終結點地址:AuthorizeEndpointPath、TokenEndpointPath等,它定義了訪問獲取授權碼以及獲取Token的地址信息。
  ● Token提供器:AuthorizationCodeProvider、AccessTokenProvider、RefreshTokenProvider負責完成對應令牌的創建和處理功能。
  ● Token的“加密”與“解密”:該功能是OAuth與Owin身份驗證的結合,通過AccessTokenFormat等ISecureDataFormat介面的實現可以將對應的Token轉換成一個  AuthenticationTicket。可參考《ASP.NET沒有魔法——ASP.NET Identity的加密與解密》文中TicketDataFormat的用法。
  ● OAuth授權服務:Provider是整個OAuth伺服器的核心,它包含了終結點的處理與響應、OAuth中的4種Access Token授權方式刷新令牌獲取Access Token的方式以及請求、客戶端的相關驗證

  

3. 為授權伺服器添加終結點

  上面介紹OAuth時介紹了終結點實際上就是用來獲取授權碼或者Access Token的,在.Net中使用Microsoft.Owin.Security.OAuth組件僅需要通過配置的形式就可以指定授權碼及Token獲取的終結點訪問地址(註:把AllowInsecureHttp配置屬性設為true,可以允許不安全的http來訪問終結點,該配置僅用於開發環境):

  

  完成後就可以通過瀏覽器訪問這兩個地址:

  

  

  可以看到是可以訪問,只不過是有錯誤的(註:請求地址的QueryString的參數參考文檔)。

4. Client的管理與驗證

   Client在OAuth中指代了所有的第三方需要訪問受限制資源的應用程式,授權伺服器為了能夠識別和驗證Client所以需要完成Client的管理以及驗證功能。(註:微軟在Microsoft.Owin.Security.OAuth組件中僅僅提供了Client驗證的介面,所以要自己實現Client數據的管理以及驗證邏輯):

  1). 添加Client實體以及對應的倉儲(本例以記憶體的方式實現倉儲,實際使用中至少應該保存資料庫):

  

  上圖是Client最基礎的屬性(註:如果還需要對Client的訪問範圍進行限制,那麼還應該加入一個Scope的列表,本例不再加入Scope的限制)。

  2). Client的倉儲:

  

  3). 實現授權伺服器對Client的驗證:

  由於授權伺服器對客戶端驗證的介面位於OAuthAuthorizationServerProvider類型中,所以首先要繼承該類型,並重載相應的驗證方法:

  

  上面代碼做了以下幾件事:
  ● 嘗試從Http請求header或者請求body中獲取Client信息,包含Id和密碼。
  ● 如果沒有Client的Id信息,那麼直接判斷為不通過驗證,如果有Client的密碼信息則保存到Owin上下文中,供後續處理使用。
  ● 使用獲得的ClientId在Client倉儲中查詢,判斷是否是一個合法的Client,如不是則判斷為不通過驗證。

  4). 驗證完成後設置該Client的重定向Url(註:該方法仍舊是重載OAuthAuthorizationServerProvider類型中的方法):

  

5. 添加授權碼提供器

  授權碼的生成是授權伺服器終結點的一項功能,當使用授權碼模式時用戶訪問Client會被引導跳轉到授權伺服器完成身份驗證(登錄),隨後又攜帶授權碼跳轉回Client,Client使用該授權碼獲取Access Token。在OAuth的.Net實現中,需要通過在配置中配置一個類型為IAuthenticationTokenProvider的令牌提供器,該提供器用於創建解析令牌,這裡的創建實際就是用戶完成登錄後授權碼的生成以及授權碼和用戶登錄身份信息的關聯,而解析實際就是根據授權碼獲得對應用戶身份信息並生成Access Token的過程。

  下麵就通過實現IAuthenticationTokenProvider的方式實現一個自定義授權碼提供器:

  

  從上面代碼可以看出這個提供器的核心功能是以Guid的方式生成一個鍵值(授權碼)保存了當前用戶的信息,當解析時通過該鍵值(即授權碼)獲取用戶身份信息。(註:AuthenticationTokenCreateContext對象用於對當前用戶身份信息AuthenticationTicket對的的序列化和反序列化)

  完成後將該提供器配置到授權伺服器中間件中:

  

6. 為授權伺服器添加用戶授權提示頁面

  當用戶訪問授權碼終結點時理應讓用戶知道Client需要他的授權,為此在ASP.NET MVC程式中需要添加一個路由與授權碼終結點地址匹配的Controller、Action以及View:

  1). Controller及Action(註:該Action需要通過身份驗證,如果沒有需要跳轉到登錄頁面完成身份驗證後才可訪問):

  

  2). View:顯示授權提示

  

7. 運行程式

  1). 訪問授權碼終結點獲取授權碼:http://localhost:59273/oauth2/authorize?response_type=code&client_id=test1

  由於沒有登錄,所以先跳轉到登錄頁面。

  

  完成登錄後跳轉回授權頁面:

  

  點擊授權按鈕後,攜帶授權碼跳轉到test1這個client的重定向Url(註:此處test1這個Client設置的Url就是授權伺服器本身,所以看上去沒有做重定向)

  

  得到授權碼後,攜帶授權碼訪問Access Token終結點獲取Access Token(註:這裡使用Chrome瀏覽器的Postman拓展來實現請求的模擬):

  

  註:上面響應信息中的access_token包含了加密後用戶的身份信息,其加密過程可參考基於Cookie的用戶信息加密過程。ASP.NET沒有魔法——ASP.NET Identity的加密與解密

實現基於Access Token的身份驗證

  上面介紹瞭如何基於授權碼模式獲得Access Token,接下來將介紹如何使用Access Token來訪問受限制的資源(註:本例中的資源伺服器與授權伺服器位於同一實例中,所以當資源伺服器對access token解密時,能夠保證與授權伺服器用於生成access token所用密鑰一致,能夠正常解密,這裡的Access Token和基於Cookie的身份驗證中的身份驗證Cookie性質是相同的,都是將用戶的身份信息序列化後的加密字元串)

  1. 在Startup類中添加基於Bearer的OAuth身份驗證中間件:

  

  2. 添加訪問受限制的資源:

  

  3. 訪問受限資源:

  未添加授權信息直接跳轉到登錄頁面。

  

  添加Access Token後可正常訪問資源:

  

加入Refresh Token支持

  上面使用授權碼模式生成的Access Token是存在過期時間的(實際上無論什麼方式生成的Access Token都存在過期時間),Token過期後又不可能讓用戶再授權一次,所以需要使用Refresh Token來定期刷新Access Token,.Net中實現Refresh Token的方式與授權碼類似,在生成Refresh Token的同時會關聯用戶的身份信息,後續可以使用這個Refresh Token來生成新的Access Token。

  1. 創建Refresh Token提供器(實現方式與授權碼提供器基本一致):

  

   2. 為授權伺服器配置Refresh Token提供器:

  

  3. 再次獲取到授權碼後,根據該授權碼獲取Access Token,返回信息中將攜帶Refresh Token:

  

  4. 根據Refresh Token刷新Access Token:

  

實現通過用戶密碼模式獲取Access Token

  上面介紹了授權碼模式的實現方式,但這種方式的核心實際上是建立了一個授權碼和用戶信息的映射(包括刷新令牌方式也是建立了刷新令牌與用戶信息的映射),後續的Access Token實際上是使用這個了用戶信息生成的。換句話用戶信息才是核心,.Net中用戶信息的體現從底到高分別是:IIdentity->ClaimsIdentity-> AuthenticationTicket,關於用戶的身份信息可參考:《ASP.NET沒有魔法——ASP.NET Identity與授權》,在基於授權碼的模式時通過在授權伺服器的登錄功能獲得了用戶信息,而基於用戶名密碼模式時沒有這個跳轉登錄環節,所以需要直接通過用戶名密碼來獲取用戶信息,其實現如下重載了OAuthAuthorizationServerProvider類型的GrantResourceOwnerCredentials方法:

  

  該方法從Owin環境中獲取Identity中的UserManager對象,通過UserManager來驗證用戶是否存在,如果存在則將使用用戶信息來創建一個ClaimsIdentity對象(註:此處是省略的實現,正常實現可根據需求參考Cookie驗證方式將Scope或者Role等信息也添加到Identity對象中)。另UserManager是通過以下代碼添加到Owin上下文中的,它的Key值是"AspNet.Identity.Owin:" + typeof(ApplicationUserManager).AssemblyQualifiedName。

  

  使用用戶名密碼獲取Access Token:

  

實現客戶端模式獲取Access Token

  客戶端模式和用戶名密碼模式是類似的,它是通過Client的Id以及密碼來進行授權,使用的是Client相關的信息,它的實現方式如下,重載GrantClientCredentials方法,通過客戶端驗證後的id和密碼信息來驗證改Client是否合法,對於合法的Client為其創建Identity對象(註:此處可以根據實際需求在Identity中添加相應的屬性):

  

  使用Client信息獲取Access Token:

  

  以上就是.Net中對於OAuth的實現,另外.Net中沒有提供簡化模式的介面,但是提供了一個GrantCustomExtension,也就是說授權模式是可拓展的。

關於.Net中OAuth相關令牌的加密說明

  本例中除了授權碼以及刷新令牌是2個Guid連接外,訪問令牌(包括所有授權模式生成的令牌)以及授權碼對應的用戶信息、刷新令牌對應的用戶信息都是經過加密的,其加解密對象創建過程如下,具體內容可參考《ASP.NET沒有魔法——ASP.NET Identity的加密與解密

  

小結

  本章內容介紹了OAuth2.0協議相關的內容,並通過一個ASP.NET MVC程式基於微軟的Microsoft.Owin.Security.OAuth組件實現了該協議中的大部分功能。使用OAuth來實現身份驗證可以讓我們的應用程式從Web拓展至任意的平臺上運行,但這樣的實現仍舊是存在一些問題的,在下一篇文章中將對這些問題進一步的討論和介紹。

PS.這一章內容比較多,如有問題可以在評論區留言,另外最近事情比較多,所以更新慢了,感謝大家的支持。

參考:

  https://stackoverflow.com/questions/39909419/jwt-vs-oauth-authentication
  http://www.cnblogs.com/linianhui/p/oauth2-authorization.html
  http://www.c-sharpcorner.com/UploadFile/4b0136/openid-connect-availability-in-owin-security-components/
  https://docs.microsoft.com/en-us/aspnet/aspnet/overview/owin-and-katana/owin-oauth-20-authorization-server
  https://security.stackexchange.com/questions/94995/oauth-2-vs-openid-connect-to-secure-api
  http://bitoftech.net/2014/07/16/enable-oauth-refresh-tokens-angularjs-app-using-asp-net-web-api-2-owin/

 本文鏈接:http://www.cnblogs.com/selimsong/p/8037717.html 

ASP.NET沒有魔法——目錄


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • .NET Core 兩種GC模式: Server GC / Workstation GC Server GC : 主要應用於多處理器系統,並且作為ASP.NET Core宿主的預設配置。它會為每個處理器都創建一個GC Heap,並且會並行執行回收操作。該模式的GC可以最大化吞吐量和較好的收縮性。這種... ...
  • 一.什麼是值類型?什麼引用類型? 1.值類型的值是存儲在棧上的。引用類型是存在堆上的。 2.值類型變數聲明之後,不管是否已經分配記憶體,編譯器在堆上為其分配記憶體。 3.引用類型聲明的時候,這時候只在棧中分配一小片記憶體用於容納一個地址,此時候並沒有為其分配堆上的記憶體地址,當new一個實例的時候,真正創建 ...
  • PS:寫這個主要是基礎差,寫這麼一個主要是為了自己查漏補缺,不會的搞會了。會了搞的更會。順便整理知識。 目錄 1.C#知識點之:值類型和引用類型 ...
  • 先來看看下麵一個類中的一些方法: class Bc { public double Add(double number1, double number2) { return number1 + number2; } public double Multiply(double number1, dou ...
  • 最近做的項目,上線後一切正常,過段時間管理員反饋用戶導出EXCEL報錯,前臺獲取用戶列表不顯示,查找問題找到是微信昵稱、emoji表情導致報錯, emoji表情介紹 由於微信介面中對於emoji表情使用的是UTF-8的二進位字元串,並沒有解碼,表現就是當收到微信端用戶發來的emoji表情時,顯示為一 ...
  • 類只能繼承一個類,不能繼承多個類,但可以繼承多個介面Interface。 類是對象的抽象,抽象類是類的抽象,而介面是行為的抽象。 下麵Insus.NET創建2個介面: 介面是統一行為,抽象是從現在有代碼中,把上同代碼抽取出來的一個抽象方法,而介面卻是相反。不清楚有什麼子類存在,行為具體實現也不確定。 ...
  • 通過前面的文章,已經學習了怎麼使用線程,怎麼使用線程同步,怎麼使用線程池,怎麼使用任務並行庫。儘管通過上面的學習,對於線程的使用越來越簡單。有沒有更簡單的方法呢。 C# 5.0之後,微軟在c#語言中添加了兩個關鍵字async與await,這是在TPL上面的更高一級的抽象,真正簡化了異... ...
  • 抽象類,有3個特點: 第1個,不能被實例化。 第2個,類中的抽象方法在繼承的子類中必須重寫。 第3個,類一旦有抽象方法出現,那這個類必須定義為抽象類。 現實開發中,發現有共同的代碼,可以把這些共同的代碼放在一個抽象類中。舉個例子,計算四邊形的周長。 矩形,長方形,正方形: class Rectang ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...