{"id":26271870,"url":"https://github.com/igouist/demo.swaggerui.jwt","last_synced_at":"2025-03-14T07:15:02.262Z","repository":{"id":165431924,"uuid":"385475332","full_name":"Igouist/Demo.SwaggerUI.Jwt","owner":"Igouist","description":"JWT 與 Swagger UI 測試專案，請參見 https://igouist.github.io/post/2021/10/swagger-enable-authorize/","archived":false,"fork":false,"pushed_at":"2024-04-10T13:32:57.000Z","size":23,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-03-08T14:44:46.988Z","etag":null,"topics":["jwt","swagger-ui"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Igouist.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2021-07-13T04:30:55.000Z","updated_at":"2024-04-10T13:30:04.000Z","dependencies_parsed_at":"2024-04-10T15:30:24.681Z","dependency_job_id":"287b4827-bb02-4318-9840-93a16f9df7cc","html_url":"https://github.com/Igouist/Demo.SwaggerUI.Jwt","commit_stats":null,"previous_names":["igouist/demo.swaggerui.jwt"],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Igouist%2FDemo.SwaggerUI.Jwt","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Igouist%2FDemo.SwaggerUI.Jwt/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Igouist%2FDemo.SwaggerUI.Jwt/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Igouist%2FDemo.SwaggerUI.Jwt/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Igouist","download_url":"https://codeload.github.com/Igouist/Demo.SwaggerUI.Jwt/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243538130,"owners_count":20307104,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["jwt","swagger-ui"],"created_at":"2025-03-14T07:15:01.615Z","updated_at":"2025-03-14T07:15:02.251Z","avatar_url":"https://github.com/Igouist.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# 在 Swagger UI 加上驗證按鈕，讓 Request Header 傳遞 Authorize Token\nJWT 與 Swagger UI 測試專案\n\n\u003e 本文同步發表於部落格（好讀版 →）：https://igouist.github.io/post/2021/10/swagger-enable-authorize/\n\n![Image](https://i.imgur.com/XjZLvSZ.png)\n\n在先前的 [菜雞新訓記 (4): 使用 Swagger 來自動產生簡單好看可測試的 API 文件吧](/post/2021/05/newbie-4-swagger) 中，我們介紹了在 .net Core 環境使用 **Swashbuckle** 套件來產生 Swagger 文檔，並且直接在 Swagger UI 中呼叫 API 來進行測試。\n\n但很多時候，我們的 API 會需要先驗證才能使用，例如**在 Header 傳遞 Token 來驗證身分**等等。這時候 Swagger UI 就會整個廢掉，打了都會出錯，很不方便。\n\n因此這篇文章就紀錄一下如何在 Swagger UI 上加入 Authorize Token 的傳遞，讓 Swagger UI 在需要身分驗證的環境也能直接呼叫使用。\n\n\u003c!--more--\u003e\n\n## 環境佈置\n\n首先範例專案直接參考 The Will Will Web 的這篇 [如何在 ASP.NET Core 3 使用 Token-based 身分驗證與授權 (JWT)](https://blog.miniasp.com/post/2019/12/16/How-to-use-JWT-token-based-auth-in-aspnet-core-31)，捏一個**需要登入取得 JWT Token，然後將 Token 放到 Header 的 Authorize 才能查詢資料**的專案。\n\n專案的大致狀況和目前 Swagger UI 如下，有登入和查詢兩支方法：\n\n![Image](https://i.imgur.com/tfz8cIo.png)\n\n那我們沒有登入的情況直接呼叫查詢方法就會報錯：\n\n![Image](https://i.imgur.com/08QLPLM.png)\n\n登入的話就能拿到 Token：\n\n![Image](https://i.imgur.com/ffzV49y.png)\n\n用 Postman 試試看把 Token 掛到 Authorization，查詢就可以成功：\n\n![Image](https://i.imgur.com/fQhcIdC.png)\n\n但是我們的 Swagger 還沒有提供能放 Authorization Token 的地方，這樣用起來就會 Hen 不方便。\n\n因此目標就是：可以將這組 Token 放到 Header 裡，讓查詢方法不要報錯。讓我們開始吧！\n\n## 加入 Authorize 設置\n\n首先讓我們先找到註冊 Swagger 產生器的地方，以先前的 Swagger 介紹文為例的話，會是在  `Startup.cs` 的 `ConfigureServices` 裡的 `AddSwaggerGen`。\n\n裡面可能已經有包含 API 簡介等欄位，例如：\n\n```csharp\n// 註冊 Swagger 產生器\nservices.AddSwaggerGen(options =\u003e\n{\n    // API 服務簡介\n    options.SwaggerDoc(\"v1\", new OpenApiInfo\n    {\n        Version = \"v1\",\n        Title = \"JWT Demo\",\n        Description = \"菜雞嘗試 JWT 的範例 API\",\n        TermsOfService = new Uri(\"https://igouist.github.io/\"),\n        Contact = new OpenApiContact\n        {\n            Name = \"Igouist\",\n            Email = string.Empty,\n            Url = new Uri(\"https://igouist.github.io/about/\"),\n        }\n    });\n\n    // 讀取 XML 檔案產生 API 說明\n    var xmlFile = $\"{Assembly.GetExecutingAssembly().GetName().Name}.xml\";\n    var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);\n    options.IncludeXmlComments(xmlPath);\n});\n```\n\n首先讓我們用 Security Scheme 來告訴 Swagger 我們的驗證資訊吧。在 `AddSwaggerGen` 中加上 `AddSecurityDefinition`：\n\n```csharp\noptions.AddSecurityDefinition(\"Bearer\", \n    new OpenApiSecurityScheme\n    {\n        Name = \"Authorization\",\n        Type = SecuritySchemeType.ApiKey,\n        Scheme = \"Bearer\",\n        BearerFormat = \"JWT\",\n        In = ParameterLocation.Header,\n        Description = \"JWT Authorization\"\n    });\n```\n\n加了之後就能在 Swagger UI 看見我們的 Authorize 按鈕囉：\n\n![Image](https://i.imgur.com/Opk7XZW.png)\n\n點開就會看到我們上面定義的內容：\n\n![Image](https://i.imgur.com/SpvrFXG.png)\n\n不過現在還不會作用，我們還得讓全部的呼叫都自動加上這個 Token 才行。接著在 `AddSwaggerGen` 中加上 `AddSecurityRequirement`，並且讓他去抓我們前面設定好 \"Bearer\" 的 SecurityScheme：\n\n```csharp\noptions.AddSecurityRequirement(\n    new OpenApiSecurityRequirement\n    {\n        {\n            new OpenApiSecurityScheme\n            {\n                Reference = new OpenApiReference\n                {\n                    Type = ReferenceType.SecurityScheme,\n                    Id = \"Bearer\"\n                }\n            },\n            new string[] {}\n        }\n    });\n```\n\n注意 `Id` 要和我們上一步加入的 `Scheme` 一致呦。\n\n\u003e 補充：OpenApiSecurityRequirement 是一個 Dictionary，所以中間那層 `{}` 不要忘囉\n\n加完之後現在的 `AddSwaggerGen` 大概是這個樣子的：\n\n```csharp\n// 註冊 Swagger 產生器\nservices.AddSwaggerGen(options =\u003e\n{\n    // API 服務簡介\n    options.SwaggerDoc(\"v1\", new OpenApiInfo\n    {\n        Version = \"v1\",\n        Title = \"JWT Demo\",\n        Description = \"菜雞嘗試 JWT 的範例 API\",\n        TermsOfService = new Uri(\"https://igouist.github.io/\"),\n        Contact = new OpenApiContact\n        {\n            Name = \"Igouist\",\n            Email = string.Empty,\n            Url = new Uri(\"https://igouist.github.io/about/\"),\n        }\n    });\n\n    // Authorization\n    options.AddSecurityDefinition(\"Bearer\", \n    new OpenApiSecurityScheme\n        {\n            Name = \"Authorization\",\n            Type = SecuritySchemeType.ApiKey,\n            Scheme = \"Bearer\",\n            BearerFormat = \"JWT\",\n            In = ParameterLocation.Header,\n            Description = \"JWT Authorization\"\n        });\n\n    options.AddSecurityRequirement(\n        new OpenApiSecurityRequirement\n        {\n            {\n                new OpenApiSecurityScheme\n                {\n                    Reference = new OpenApiReference\n                    {\n                        Type = ReferenceType.SecurityScheme,\n                        Id = \"Bearer\"\n                    }\n                },\n                new string[] {}\n            }\n        });\n\n    // 讀取 XML 檔案產生 API 說明\n    var xmlFile = $\"{Assembly.GetExecutingAssembly().GetName().Name}.xml\";\n    var xmlPath = Path.Combine(AppContext.BaseDirectory, xmlFile);\n    options.IncludeXmlComments(xmlPath);\n});\n```\n\n## 完工測試\n\n接著就讓我們啟動試試吧！\n\n首先讓我們把登入的 Token 放到 Authorization 按鈕的欄位裡，不要忘記加上 Bearer：\n\n![Image](https://i.imgur.com/R0kbhqC.png)\n\n![Image](https://i.imgur.com/TlChzMH.png)\n\n加入之後就 Close，讓我們打看看查詢的方法：\n\n![Image](https://i.imgur.com/Jyyjqqe.png)\n\n可以看到成功拿到值啦！\n\n從開發工具也可以看到 Header 的確有加上 Bearer Token 了：\n\n![Image](https://i.imgur.com/7L0o40m.png)\n\n大功告成，打完收工！\n\n## 參考資料\n\n### JWT\n- [[ASP.NET Core] 加上JWT身份驗證 - Ian Chen](https://dotblogs.com.tw/Null/2020/06/04/212347)\n- [如何在 ASP.NET Core 2.2 使用 Token-based 身分驗證與授權 (JWT) - The Will Will Web](https://blog.miniasp.com/post/2019/10/13/How-to-use-JWT-token-based-auth-in-aspnet-core-22)\n- [如何在 ASP.NET Core 3 使用 Token-based 身分驗證與授權 (JWT) - The Will Will Web](https://blog.miniasp.com/post/2019/12/16/How-to-use-JWT-token-based-auth-in-aspnet-core-31)\n\n### Swagger\n- [Swagger - 在 Headers 中新增 API Token 驗證 ~ m@rcus 學習筆記 (marcus116.blogspot.com)](https://marcus116.blogspot.com/2019/01/add-token-authorization-requestheaders-using-swagger-in-webapi-.html)\n- [c# - Setting up Swagger (ASP.NET Core) using the Authorization headers (Bearer) - Stack Overflow](https://stackoverflow.com/questions/43447688/setting-up-swagger-asp-net-core-using-the-authorization-headers-bearer)\n- [Authentication and Authorization - swagger.io](https://swagger.io/docs/specification/authentication/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Figouist%2Fdemo.swaggerui.jwt","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Figouist%2Fdemo.swaggerui.jwt","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Figouist%2Fdemo.swaggerui.jwt/lists"}