在 .NET 9.0 Web API 中实现 Scalar 接口文档及JWT集成

示例代码:https://download.csdn.net/download/hefeng_aspnet/90408075

介绍

随着 .NET 9 的发布,微软宣布他们将不再为任何 .NET API 项目提供默认的 Swagger gen UI。以前,当我们创建 .NET API 项目时,微软会自动添加 Swagger Swashbuckle 包,该包提供了app.UseSwagger()和app.UseSwaggerUI() 等方法。这些方法显示了带有预定义 UI 的 API 文档,可直接在浏览器中进行测试,而无需使用 Postman 等任何第三方应用程序。但是,Swagger 不再与 .NET 9 Web API 项目集成。做出此决定是因为该包最近没有得到妥善维护,并且许多用户报告的问题仍未解决。

微软团队创建了一个名为 Microsoft.AspNetCore.OpenApi 的新包,它提供了类似于 Swagger 的内置 OpenAPI 文档生成功能。但是,这只提供了所有端点和架构定义的 JSON 文档,而浏览器中不会显示任何 UI。这一变化的主要目的是让用户实现他们喜欢的 UI 库,无论是 Swagger 还是任何其他替代方案。微软删除默认的 Swagger 包并不意味着您不能在项目中再次安装 Swagger------您可以添加它并执行与以前相同的所有操作。

目前有许多 Swagger 的替代方案,但在本文中,我们将讨论并在我们的 API 项目中实现 Scalar。继 Swagger 之后,Scalar 在开发人员中越来越受欢迎。

创建新项目

当您使用 .NET 9 创建新项目时,它会询问您是否要配置 OpenAPI 支持。如果您选中此复选框,它会将 Microsoft.AspNetCore.OpenApi 包添加到您的项目中,并在 program.cs 文件中注册 OpenAPI 服务,如下所示:

var builder = WebApplication.CreateBuilder(args);

builder.Services.AddOpenApi();

var app = builder.Build();

if (app.Environment.IsDevelopment())

{

app.MapOpenApi();

}

现在,当您运行 API 并导航到/OpenApi/v1.json时,它将显示默认生成的文档,其中包含有关您的端点和您使用的所有模式的信息,如下图所示:

配置 Scalar.NET

首先,打开你的包管理器并安装Scalar.AspNetCore。

然后,只需在program.cs文件中添加app.MapScalarApiReference();即可映射 Scalar UI 的所有 API 引用和路由。

现在,如果您转到/Scalar/V1,您将看到端点的漂亮 UI。在这里,我只有一个端点,所以它看起来像这样。

配置标量的选项

您可以配置多个选项并更改 UI 的设置。一些配置包括。

1、Title:设置显示在浏览器选项卡顶部的文档标题

2、DarkMode: true/false 启用或禁用暗模式

3、Favicon:设置文档的图标

4、DefaultHttpClient:在浏览器中加载 UI 时显示默认 HTTP 客户端。它显示相应编程语言的代码实现。

5、HideModels: true/false 设置是否显示模型定义

6、Layout:设置 Scalar UI 的布局/主题

7、ShowSidebar: true/false 设定是否显示侧边栏。这仅在您选择了现代布局时才有效。

还有更多。

默认打开 Scalar UI

您可能已经注意到,我们每次都必须在 URL 中输入 scalar/v1 才能看到 Scalar UI。我们可以更改启动 URL,这样就不必重复执行此操作。打开launchsettings.json文件并将启动 URL 添加到您的配置文件中。我已为 HTTP 和 HTTPS 添加了它。您可以根据您的要求进行配置。

使用授权和 JWT 令牌

在大多数 API 中,我们都会实现 JWT 令牌或其他类型的令牌身份验证。因此,我添加了几行代码来使用 JWT 令牌实现授权。我还为此安装了 Microsoft.AspNetCore.Authentication.JwtBearer 包。

builder.Services

.AddAuthorization()

.AddAuthentication(x =>

{

x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;

x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

})

.AddJwtBearer(x =>

{

x.RequireHttpsMetadata = false;

x.SaveToken = true;

x.TokenValidationParameters = new TokenValidationParameters

{

ValidateIssuerSigningKey = false,

IssuerSigningKey = new SymmetricSecurityKey(Encoding.ASCII.GetBytes("your_jwt_key")),

ValidateIssuer = false,

ValidateAudience = false

};

});

app.UseAuthentication();

app.UseAuthorization();

app.MapGet("/test1", () => "This is test 1 endpoint")

.WithName("Test1")

.RequireAuthorization();

当我调用此 test1 端点时,它给出了401 错误(未经授权)。那么,我们如何解决这个问题呢?我们可以简单地传递一个身份验证令牌,但如果你看看 Scalar,你会发现没有选项可以在他们的 UI 上添加身份验证/承载令牌。即使我在MapScalarApiReference中添加了PreferredSecurityScheme作为承载者,也没有针对身份验证类型的选项。

options.Authentication = new ScalarAuthenticationOptions

{

PreferredSecurityScheme = "Bearer"

};

如果您在标头中将身份验证令牌与授权密钥一起传递,则它可以工作,但这不是我们想要的,对吗?我们想要一个类似于 Swagger 的界面,它显示在主页或各个端点上添加令牌的选项。这是 Scalar 的一个问题,已在其 GitHub 存储库中报告:https://github.com/scalar/scalar/issues/4055。

但是,有一种方法可以实现我们想要的并解决这个问题。我们可以使用 OpenAPI 中的文档转换器功能,微软在这里提供了详细的文档:https://learn.microsoft.com/en-us/aspnet/core/fundamentals/openapi/customize-openapi ?view=aspnetcore-9.0 。

使用这个转换器,我们可以通知 Scalar 我们想要在 UI 上显示身份验证选项,以便 Scalar 可以将其添加到主页以及各个端点上。

这是压缩类:

internal sealed class BearerSecuritySchemeTransformer : IOpenApiDocumentTransformer

{

private readonly IAuthenticationSchemeProvider _authenticationSchemeProvider;

public BearerSecuritySchemeTransformer(IAuthenticationSchemeProvider authenticationSchemeProvider)

{

_authenticationSchemeProvider = authenticationSchemeProvider;

}

public async Task TransformAsync(OpenApiDocument document, OpenApiDocumentTransformerContext context, CancellationToken cancellationToken)

{

var authenticationSchemes = await _authenticationSchemeProvider.GetAllSchemesAsync();

if (authenticationSchemes.Any(authScheme => authScheme.Name == "Bearer"))

{

var requirements = new Dictionary<string, OpenApiSecurityScheme>

{

"Bearer" = new OpenApiSecurityScheme

{

Type = SecuritySchemeType.Http,

Scheme = "bearer",

In = ParameterLocation.Header,

BearerFormat = "JWT"

}

};

document.Components ??= new OpenApiComponents();

document.Components.SecuritySchemes = requirements;

foreach (var operation in document.Paths.Values.SelectMany(path => path.Operations))

{

operation.Value.Security.Add(new OpenApiSecurityRequirement

{

[new OpenApiSecurityScheme

{

Reference = new OpenApiReference

{

Id = "Bearer",

Type = ReferenceType.SecurityScheme

}

}] = Array.Empty<string>()

});

}

}

}

}

此代码将在主页和所有请求端点添加一个身份验证选项,您可以在其中传递令牌来发送请求。

此代码修改了 OpenAPI/Scalar 文档以显示 API 支持 Bearer 令牌认证。

1、它首先检查 API 是否启用了"Bearer"身份验证

2、如果存在 Bearer 身份验证,它会在 OpenAPI/Scalar 中添加安全方案

3、此安全方案告诉 OpenAPI/Scalar,请求应在授权标头中包含 JWT(JSON Web Token)

4、默认情况下,这仅添加了对身份验证的支持,但在 OpenAPI/Scalar UI 中不需要它

5、为了使 UI 中看起来需要身份验证,代码循环遍历所有 API 端点并将它们标记为需要 Bearer 令牌

下面的循环就是这么做的:

foreach (var operation in document.Paths.Values.SelectMany(path => path.Operations))

{

operation.Value.Security.Add(new OpenApiSecurityRequirement

{

[new OpenApiSecurityScheme

{

Reference = new OpenApiReference

{

Id = "Bearer",

Type = ReferenceType.SecurityScheme

}

}] = Array.Empty<string>()

});

}

这可确保每次生成 OpenAPI/Scalar 文档时都会添加安全方案和要求。

如果您想要真正强制身份验证,则需要向控制器添加Authorize或在 Minimal API 中添加 RequireAuthorization() 。

现在您可以在此输入中传递您的令牌,它将被传递到服务器而不会出现任何问题,并且您将不再收到 401 错误。

您可以下载该示例项目:https://download.csdn.net/download/hefeng_aspnet/90408075

如果您喜欢此文章,请收藏、点赞、评论,谢谢,祝您快乐每一天。

相关推荐
我不会起名字3227 天前
Redis 从 0 到 1(十九):JWT 还是 Redis Session?登录态存储的 Go 实现
redis·go·jwt·session·登录态
Thanks_ks8 天前
Cookie 和 Session 到底是什么关系——登录态是怎么维持的
分布式·http·jwt·cookie·session·后端开发·登录态
枫子有风11 天前
卡码网盘项目深挖
java·redis·jwt·es·pgvector
FungLeo12 天前
成为全栈·Go 后端篇·跨语言认证兼容:Node 与 Go 如何互认 JWT 和密码
golang·go·jwt·身份认证·成为全栈·bcrypt
积流成海21 天前
JWT 解析:三段结构、过期时间换算与常见误区
jwt·盘子工具站
FungLeo1 个月前
成为全栈·Flutter App 篇·Refresh Token 旋转与并发 401:安全存储与会话代次
flutter·jwt·移动安全·身份认证·token刷新·成为全栈
豆角焖肉1 个月前
SpringBoot+JWT 实现前后端分离登录鉴权
java·开发语言·spring boot·jwt·前后端分离·登录认证
CSharp精选营1 个月前
Blazor 里 JWT 过期,用户正下单就被踢
认证·jwt·webassembly·blazor·令牌刷新
白帽攻防录1 个月前
SRC 挖洞:WSO2 JWT 算法混淆绕过深度复盘,CVE-2026-5430 不支持的算法怎么变成管理员
网络·算法·安全·网络安全·jwt
EatFan1 个月前
Go语言全栈实战:基于 Gin + Vue + JWT + RBAC 从零搭建前后端分离权限管理系统
vue.js·golang·go·vue·gin·jwt·rbac