|從0到1的建立Web API專案|以 JWT 功能 + Swagger 為例

Sharon
appxtech
Published in
7 min readNov 18, 2021

今天要使用 Visual Studio 從頭建立 Web API 專案,會分享在建立時遇到的小問題(坑洞),並且介紹專案內使用了哪些組件,本篇文章會分成三大主題來講解:

ㄧ、JWT 建立 + Swagger 搭配 JWT

二、Session 設置

三、Middleware 統一回傳格式

四、Model FluentValidation 驗證

除了上述三大主題之外,也會一步步走完整個專案建立。首先先開啟一個空白的 API 專案(如圖一),並選擇要使用的 framework (這裡以 .NET 5.0 作為示範)

圖一 建立專案畫面

開啟後 Startup.cs 已內建好基本 Swagger (如圖二),按下執行時會有一個內建 API 可以進行測試(如圖三)

圖二 Startup.cs
圖三 swagger

接下來可以試著建立 Controller 與需要的函式,這裡以一組 POST/GET 作為示範,啟用 Swagger 後可以發現,我們不需要通關密碼就可以呼叫 API,任何人都可以隨意存取,意味著陌生人可以來開啟你家大門並且自由拿取你家中寶藏,這是一件很危險的事情,所以我們要在專案中設置大門與身份識別,在呼叫 API 時我們需要對呼叫者的身份做授權或驗證。

在這裡使用的機制就是 JSON Web Token(JWT),JWT 是一種 JSON 的開放標準,用途是在伺服器端(Server)與客戶端(Client)之間安全的將訊息作為 JSON 物件的傳輸,身份識別的驗證流程大致如下:

(1) Client 會向 Server 發送登入需求,登入成功後 Client 會取得一組 Token 並且存取起來。

(2) 之後 Client 需要呼叫 API 時,會一併將 Token 回傳(通常是放在 Header)讓 Server 去驗證,驗證通過後才可以取得呼叫的內容。

JWT 的架構原理就不多作介紹,可以參考底下附件的文章說明。接著我們來實作如何產生出 JWT 並且讓 Client 取得,首先先建立 JWT 設定參數 發行人(Issuer)/用來加密的金鑰字串(SignKey)/有效期限(ExpireSec),將這三個參數放在 appsettings.Json方便日後改動。

並且在 Startup 內建立 Configuration,方便整個專案讀取 appsettings.Json 參數。

建立 JwtProvider.cs 檔案(可以自行決定放在哪一個資料夾內,這裡示範是開一資料夾名為Provider)呼叫 IConfiguration 會出現需要 using Configuration 組件(如圖四),安裝完後我們就可以繼續完成注入 IConfiguration 並取得 appsettings.Json 參數。

圖四 JwtProvider.cs

參數定義好後,我們先來安裝 JWT 的組件,在 NuGet(如圖五) 中搜尋Microsoft.AspNetCore.Authentication.JwtBearer 並且安裝至專案,建立一個使用者的 Model,裡面參數設定為使用者需要的登入資訊,在 JwtProvider 新增一 JWT 的產生函式(GenerateToken)中呼叫此 Model,並將 Model 資訊加入 JWT 中(GenerateClaims),設定以下參數:

(1) 發行人(Issuer)。

(2) 用來加密的金鑰字串(SignKey)。

(3) 有效期限(ExpireSec)。

圖五 NuGet

在 Controller 注入 JwtProvider 後,建立一個登入的 API 並呼叫 JwtProvider 中的 GenerateToken 來建立 Token,並且在函式上設定 API 驗證方式,分為以下兩種:

(1) [AllowAnonymous] 用來允許未經驗證的使用者存取個別動作,意思就是這個函式會不受 JWT 的限制即可呼叫

(2) [Authorize] 需要經過驗證才可以存取個別動作,此函式會受到 JWT 的限制

而我們需要設定全局的 API 需要受到驗證時,則可以建立一基本的 Controller 套上[Authorize],讓所有 Controller 繼承它,會使所有函式都需要通過驗證(當然有套上[AllowAnonymous]除外)。

這時候啟用 Swagger 後測試登入API,恭喜你會得到一個錯誤(如圖六)!

圖六 swagger
System.InvalidOperationException: Unable to resolve service for type 'TESTAPI.Provider.JwtProvider' while attempting to activate 'TESTAPI.Controllers.LoginController'.

錯誤中提示我們 Controller 並不認識且無法解析 JwtProvider,這時候我們要在 Startup 中的 ConfigureServices 註冊 JwtProvider,再次啟用 Swagger 就會取得 JWT (如圖七),接下來就要來驗證剛剛創造的 JWT 是否能通過驗證,並成功呼叫 API。

圖七 swagger

在 Startup 中的 ConfigureServices 註冊 Authentication 驗證服務,並在 TokenValidationParameters 中可以詳細設定需要驗證的內容,大致上可以分為以下幾種驗證內容:

(1) ValidIssuer:發行人。

(2) ValidateLifetime:驗證有效時間是否失效。

(3) ValidateIssuerSigningKey:驗證加密的金鑰字串。

(4) ValidateAudience : 驗證受眾是否有效。

啟用 Swagger 後,我們可以發現並沒輸入 JWT 的地方,因為需要在 Startup 中的 ConfigureServices 註冊 Swagger 的安全限制,並且在 Configure 加入 UseAuthentication,否則 JWT 驗證會一直不通過,啟用 Swagger後就可以看到右上角多了一個鎖頭(如圖十),在鎖頭上輸入 Bearer + 登入API 回傳的 JWT(如圖十一),呼叫非登入 API 即可成功獲得 API 回傳內容(如圖十二)。

圖十 swagger
圖十一 swagger
圖十二 swagger

到這裡我們已經成功建立 JWT 與搭配 Swagger 的應用了,在來下一篇我們會提到 JWT 驗證成功後,怎麼取得裡面的有效資訊並放在 Session 內,在專案內如何提取 Session 所記憶的資料,我們一下篇見~

--

--