【开发日志】ASP.NET Core Minimal APIs开发日志
后端
实现登录注册
注册API
在数据库中存储/注册账户密码
登录API
检测接收来的账户密码,如果正确,则生成JWT Token返回给客户端
未配置密钥
报错信息,这是我在提交注册请求时,后端报的错,看起来是在生成JWT Token时出现了异常,导致注册API无法正常执行。
System.ArgumentNullException: Value cannot be null. (Parameter 's')at System.ArgumentNullException.Throw(String paramName)at System.Text.Encoding.GetBytes(String s)at BrainStromAPIs.AuthService.GenerateJwtToken(User user) in E:\GanX\DotNetProject\BrainStromAPIs\BrainStromAPIs\AuthService.cs:line 26at BrainStromAPIs.AppDatasEndpoints.<>c.<<RegisterAppDatasEndpoints>b__0_1>d.MoveNext() in E:\GanX\DotNetProject\BrainStromAPIs\BrainStromAPIs\AppData.cs:line 112
--- End of stack trace from previous location ---at Microsoft.AspNetCore.Http.RequestDelegateFactory.ExecuteTaskResult[T](Task`1 task, HttpContext httpContext)at Microsoft.AspNetCore.Http.RequestDelegateFactory.<>c__DisplayClass102_2.<<HandleRequestBodyAndCompileRequestDelegateForJson>b__2>d.MoveNext()
--- End of stack trace from previous location ---at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)HEADERS
=======
Accept: */*
Host: localhost:7050
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Content-Type: application/json
Cookie: Rider-bcaa2264=df76c046-993f-4586-8adf-dc509c9b148f
Origin: https://localhost:7050
Referer: https://localhost:7050/swagger/index.html
Content-Length: 47
sec-ch-ua-platform: "Windows"
sec-ch-ua: "Microsoft Edge";v="131", "Chromium";v="131", "Not_A Brand";v="24"
sec-ch-ua-mobile: ?0
sec-fetch-site: same-origin
sec-fetch-mode: cors
sec-fetch-dest: empty
priority: u=1, i
发现在生成时,调用了配置文件,但是我却没有正确的配置密钥,导致了这个问题。
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:SecretKey"]));
通过在appsettings.json中添加密钥配置,解决了这个问题。
"Jwt": {"SecretKey": "your_secret_key_here"}
密钥长度不足
报错信息,这是在注册API中,生成JWT Token时出现的异常,看起来是密钥长度不足导致的问题。
System.ArgumentOutOfRangeException: IDX10720: Unable to create KeyedHashAlgorithm for algorithm 'HS256', the key size must be greater than: '256' bits, key has '160' bits. (Parameter 'keyBytes')at Microsoft.IdentityModel.Tokens.CryptoProviderFactory.ValidateKeySize(Byte[] keyBytes, String algorithm, Int32 expectedNumberOfBytes)at Microsoft.IdentityModel.Tokens.CryptoProviderFactory.CreateKeyedHashAlgorithm(Byte[] keyBytes, String algorithm)at Microsoft.IdentityModel.Tokens.SymmetricSignatureProvider.CreateKeyedHashAlgorithm()at Microsoft.IdentityModel.Tokens.DisposableObjectPool`1.CreateInstance()at Microsoft.IdentityModel.Tokens.DisposableObjectPool`1.Allocate()at Microsoft.IdentityModel.Tokens.SymmetricSignatureProvider.GetKeyedHashAlgorithm(Byte[] keyBytes, String algorithm)at Microsoft.IdentityModel.Tokens.SymmetricSignatureProvider.Sign(Byte[] input)at Microsoft.IdentityModel.JsonWebTokens.JwtTokenUtilities.CreateEncodedSignature(String input, SigningCredentials signingCredentials)at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.WriteToken(SecurityToken token)at BrainStromAPIs.AuthService.GenerateJwtToken(User user) in E:\GanX\DotNetProject\BrainStromAPIs\BrainStromAPIs\AuthService.cs:line 36at BrainStromAPIs.AppDatasEndpoints.<>c.<<RegisterAppDatasEndpoints>b__0_1>d.MoveNext() in E:\GanX\DotNetProject\BrainStromAPIs\BrainStromAPIs\AppData.cs:line 112
--- End of stack trace from previous location ---at Microsoft.AspNetCore.Http.RequestDelegateFactory.ExecuteTaskResult[T](Task`1 task, HttpContext httpContext)at Microsoft.AspNetCore.Http.RequestDelegateFactory.<>c__DisplayClass102_2.<<HandleRequestBodyAndCompileRequestDelegateForJson>b__2>d.MoveNext()
--- End of stack trace from previous location ---at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)HEADERS
=======
Accept: */*
Host: localhost:7050
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Content-Type: application/json
Cookie: Rider-bcaa2264=df76c046-993f-4586-8adf-dc509c9b148f
Origin: https://localhost:7050
Referer: https://localhost:7050/swagger/index.html
Content-Length: 50
sec-ch-ua-platform: "Windows"
sec-ch-ua: "Microsoft Edge";v="131", "Chromium";v="131", "Not_A Brand";v="24"
sec-ch-ua-mobile: ?0
sec-fetch-site: same-origin
sec-fetch-mode: cors
sec-fetch-dest: empty
priority: u=1, i
这个问题是密钥长度不足导致的,解决方法是在appsettings.json中添加密钥配置,密钥长度至少为256位。
"Jwt": {"SecretKey": "your_32_byte_secret_key_here_XGanQAQ"}
灵感的CRUD操作
身份验证的配置问题
由于我没有正确的配置身份验证,导致了这个问题。
空的配置
builder.Services.AddAuthentication();
因为我采用的是JWT Token的身份验证方式,所以需要在配置中添加JWT Token的验证方式。
由因为我是在服务端通过使用对称密钥(HS256 算法)来签发/生成的 JWT,所以配置如下:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>{// 使用对称密钥(例如 HS256)来验证 JWTvar key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["Jwt:SecretKey"]));options.TokenValidationParameters = new TokenValidationParameters{// 设置签名密钥IssuerSigningKey = key,ValidateIssuer = false, // 如果不验证发行者,可以设置为 falseValidateAudience = false, // 如果不验证受众,可以设置为 falseValidateLifetime = true, // 验证令牌过期时间ClockSkew = TimeSpan.Zero // 过期时间允许的时钟偏差};});
Swagger如何配置身份验证密钥问题
首先,你需要在 Swagger 配置中告诉它允许传递额外的请求头。这可以通过在 Program.cs 或 Startup.cs 文件中配置 SwaggerGen 来完成。
假设你要为所有 API 添加一个名为 X-Custom-Header 的自定义头,步骤如下:
builder.Services.AddSwaggerGen(c =>
{// 允许Swagger在请求头中传递自定义头部信息c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme{In = ParameterLocation.Header,Description = "JWT Authorization header using the Bearer scheme.",Name = "Authorization",Type = SecuritySchemeType.ApiKey});c.AddSecurityRequirement(new OpenApiSecurityRequirement{{new OpenApiSecurityScheme{Reference = new OpenApiReference{Type = ReferenceType.SecurityScheme,Id = "Bearer"}},new string[] {}}});// 添加自定义头部c.OperationFilter<AddCustomHeaderOperationFilter>();
});public class AddCustomHeaderOperationFilter : IOperationFilter
{public void Apply(OpenApiOperation operation, OperationFilterContext context){// 添加自定义请求头operation.Parameters.Add(new OpenApiParameter{Name = "X-Custom-Header", // 自定义头的名称In = ParameterLocation.Header,Description = "This is a custom header for testing purposes.",Required = false // 设置为 false,如果是必需的可以设置为 true});}
}
正确的Authorization头部信息格式问题
通过查看服务器返回的信息:
发现我提交的格式有问题
www-authenticate: Bearer
以下是一个提交的示例请求,其中包含了自定义头部信息,注意Authorization的格式:
curl -X 'POST' \'https://localhost:7050/api/ideas' \-H 'accept: */*' \-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjEiLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoic3RyaW5nIiwiZXhwIjoxNzM0MjkxMjQxLCJpc3MiOiJ5b3VyX2lzc3Vlcl9oZXJlIiwiYXVkIjoieW91cl9hdWRpZW5jZV9oZXJlIn0.7G9yfuG_UGmP4r7gMvW7EzJ0QQGSRuhG-oWMgP6_5vE' \-H 'Content-Type: application/json' \-d '{"title": "string","description": "string"
}'
JWT失效问题
通过查看服务器返回的信息:
发现我提交的JWT Token已经失效
www-authenticate: Bearer error="invalid_token"
尝试不验证过期时间,但是依然失败。
我使用https://jwt.io/这个网站去验证了以下密钥,发现是有效的。
通过添加让服务器打印出验证错误日志的方法,发现还是格式问题。<>是占位符不是真实的内容。(上面示例已经被修改未正确格式)
修改后成功验证。
如何让服务器打印出验证错误日志:
添加potions.Events选项
//TODO: 查看思考以下这个打印设置的逻辑
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>{// 使用对称密钥(例如 HS256)来验证 JWTvar key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["Jwt:SecretKey"]));options.TokenValidationParameters = new TokenValidationParameters{// 设置签名密钥IssuerSigningKey = key,ValidateIssuer = false, // 如果不验证发行者,可以设置为 falseValidateAudience = false, // 如果不验证受众,可以设置为 falseValidateLifetime = false, // 验证令牌过期时间ClockSkew = TimeSpan.Zero // 过期时间允许的时钟偏差};// 添加错误处理回调options.Events = new JwtBearerEvents{OnAuthenticationFailed = context =>{// 记录验证失败的错误信息context.NoResult();context.Response.Headers.Add("Token-Error", "Invalid Token");Console.WriteLine($"Authentication failed: {context.Exception.Message}");return Task.CompletedTask;},OnChallenge = context =>{// 记录挑战失败的错误信息Console.WriteLine($"Authentication challenge: {context.ErrorDescription}");return Task.CompletedTask;}};});
Post提交灵感API问题
//TODO: 未完成,待解决的Bug,需要先分析以下问题,bug日志如下
通过查看服务器返回的信息:
System.FormatException: The input string 'string' was not in a correct format.at System.Number.ThrowFormatException[TChar](ReadOnlySpan`1 value)at System.Int32.Parse(String s)at BrainStromAPIs.AppDatasEndpoints.<>c.<<RegisterAppDatasEndpoints>b__0_2>d.MoveNext() in E:\GanX\DotNetProject\BrainStromAPIs\BrainStromAPIs\AppData.cs:line 123
--- End of stack trace from previous location ---at Microsoft.AspNetCore.Http.RequestDelegateFactory.ExecuteTaskResult[T](Task`1 task, HttpContext httpContext)at Microsoft.AspNetCore.Http.RequestDelegateFactory.<>c__DisplayClass102_2.<<HandleRequestBodyAndCompileRequestDelegateForJson>b__2>d.MoveNext()
--- End of stack trace from previous location ---at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)HEADERS
=======
Accept: */*
Host: localhost:7050
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjEiLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoic3RyaW5nIiwiZXhwIjoxNzM0MjkxMjQxLCJpc3MiOiJ5b3VyX2lzc3Vlcl9oZXJlIiwiYXVkIjoieW91cl9hdWRpZW5jZV9oZXJlIn0.7G9yfuG_UGmP4r7gMvW7EzJ0QQGSRuhG-oWMgP6_5vE
Content-Type: application/json
Cookie: Rider-bcaa2264=df76c046-993f-4586-8adf-dc509c9b148f
Origin: https://localhost:7050
Referer: https://localhost:7050/swagger/index.html
Content-Length: 47
sec-ch-ua-platform: "Windows"
sec-ch-ua: "Microsoft Edge";v="131", "Chromium";v="131", "Not_A Brand";v="24"
sec-ch-ua-mobile: ?0
sec-fetch-site: same-origin
sec-fetch-mode: cors
sec-fetch-dest: empty
priority: u=1, i
```## 后端### 实现登录注册#### 注册API
在数据库中存储/注册账户密码#### 登录API
检测接收来的账户密码,如果正确,则生成JWT Token返回给客户端
##### 未配置密钥
报错信息,这是我在提交注册请求时,后端报的错,看起来是在生成JWT Token时出现了异常,导致注册API无法正常执行。
```shell
System.ArgumentNullException: Value cannot be null. (Parameter 's')at System.ArgumentNullException.Throw(String paramName)at System.Text.Encoding.GetBytes(String s)at BrainStromAPIs.AuthService.GenerateJwtToken(User user) in E:\GanX\DotNetProject\BrainStromAPIs\BrainStromAPIs\AuthService.cs:line 26at BrainStromAPIs.AppDatasEndpoints.<>c.<<RegisterAppDatasEndpoints>b__0_1>d.MoveNext() in E:\GanX\DotNetProject\BrainStromAPIs\BrainStromAPIs\AppData.cs:line 112
--- End of stack trace from previous location ---at Microsoft.AspNetCore.Http.RequestDelegateFactory.ExecuteTaskResult[T](Task`1 task, HttpContext httpContext)at Microsoft.AspNetCore.Http.RequestDelegateFactory.<>c__DisplayClass102_2.<<HandleRequestBodyAndCompileRequestDelegateForJson>b__2>d.MoveNext()
--- End of stack trace from previous location ---at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)HEADERS
=======
Accept: */*
Host: localhost:7050
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Content-Type: application/json
Cookie: Rider-bcaa2264=df76c046-993f-4586-8adf-dc509c9b148f
Origin: https://localhost:7050
Referer: https://localhost:7050/swagger/index.html
Content-Length: 47
sec-ch-ua-platform: "Windows"
sec-ch-ua: "Microsoft Edge";v="131", "Chromium";v="131", "Not_A Brand";v="24"
sec-ch-ua-mobile: ?0
sec-fetch-site: same-origin
sec-fetch-mode: cors
sec-fetch-dest: empty
priority: u=1, i
发现在生成时,调用了配置文件,但是我却没有正确的配置密钥,导致了这个问题。
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:SecretKey"]));
通过在appsettings.json中添加密钥配置,解决了这个问题。
"Jwt": {"SecretKey": "your_secret_key_here"}
密钥长度不足
报错信息,这是在注册API中,生成JWT Token时出现的异常,看起来是密钥长度不足导致的问题。
System.ArgumentOutOfRangeException: IDX10720: Unable to create KeyedHashAlgorithm for algorithm 'HS256', the key size must be greater than: '256' bits, key has '160' bits. (Parameter 'keyBytes')at Microsoft.IdentityModel.Tokens.CryptoProviderFactory.ValidateKeySize(Byte[] keyBytes, String algorithm, Int32 expectedNumberOfBytes)at Microsoft.IdentityModel.Tokens.CryptoProviderFactory.CreateKeyedHashAlgorithm(Byte[] keyBytes, String algorithm)at Microsoft.IdentityModel.Tokens.SymmetricSignatureProvider.CreateKeyedHashAlgorithm()at Microsoft.IdentityModel.Tokens.DisposableObjectPool`1.CreateInstance()at Microsoft.IdentityModel.Tokens.DisposableObjectPool`1.Allocate()at Microsoft.IdentityModel.Tokens.SymmetricSignatureProvider.GetKeyedHashAlgorithm(Byte[] keyBytes, String algorithm)at Microsoft.IdentityModel.Tokens.SymmetricSignatureProvider.Sign(Byte[] input)at Microsoft.IdentityModel.JsonWebTokens.JwtTokenUtilities.CreateEncodedSignature(String input, SigningCredentials signingCredentials)at System.IdentityModel.Tokens.Jwt.JwtSecurityTokenHandler.WriteToken(SecurityToken token)at BrainStromAPIs.AuthService.GenerateJwtToken(User user) in E:\GanX\DotNetProject\BrainStromAPIs\BrainStromAPIs\AuthService.cs:line 36at BrainStromAPIs.AppDatasEndpoints.<>c.<<RegisterAppDatasEndpoints>b__0_1>d.MoveNext() in E:\GanX\DotNetProject\BrainStromAPIs\BrainStromAPIs\AppData.cs:line 112
--- End of stack trace from previous location ---at Microsoft.AspNetCore.Http.RequestDelegateFactory.ExecuteTaskResult[T](Task`1 task, HttpContext httpContext)at Microsoft.AspNetCore.Http.RequestDelegateFactory.<>c__DisplayClass102_2.<<HandleRequestBodyAndCompileRequestDelegateForJson>b__2>d.MoveNext()
--- End of stack trace from previous location ---at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)HEADERS
=======
Accept: */*
Host: localhost:7050
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Content-Type: application/json
Cookie: Rider-bcaa2264=df76c046-993f-4586-8adf-dc509c9b148f
Origin: https://localhost:7050
Referer: https://localhost:7050/swagger/index.html
Content-Length: 50
sec-ch-ua-platform: "Windows"
sec-ch-ua: "Microsoft Edge";v="131", "Chromium";v="131", "Not_A Brand";v="24"
sec-ch-ua-mobile: ?0
sec-fetch-site: same-origin
sec-fetch-mode: cors
sec-fetch-dest: empty
priority: u=1, i
这个问题是密钥长度不足导致的,解决方法是在appsettings.json中添加密钥配置,密钥长度至少为256位。
"Jwt": {"SecretKey": "your_32_byte_secret_key_here_XGanQAQ"}
灵感的CRUD操作
身份验证的配置问题
由于我没有正确的配置身份验证,导致了这个问题。
空的配置
builder.Services.AddAuthentication();
因为我采用的是JWT Token的身份验证方式,所以需要在配置中添加JWT Token的验证方式。
由因为我是在服务端通过使用对称密钥(HS256 算法)来签发/生成的 JWT,所以配置如下:
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>{// 使用对称密钥(例如 HS256)来验证 JWTvar key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["Jwt:SecretKey"]));options.TokenValidationParameters = new TokenValidationParameters{// 设置签名密钥IssuerSigningKey = key,ValidateIssuer = false, // 如果不验证发行者,可以设置为 falseValidateAudience = false, // 如果不验证受众,可以设置为 falseValidateLifetime = true, // 验证令牌过期时间ClockSkew = TimeSpan.Zero // 过期时间允许的时钟偏差};});
Swagger如何配置身份验证密钥问题
首先,你需要在 Swagger 配置中告诉它允许传递额外的请求头。这可以通过在 Program.cs 或 Startup.cs 文件中配置 SwaggerGen 来完成。
假设你要为所有 API 添加一个名为 X-Custom-Header 的自定义头,步骤如下:
builder.Services.AddSwaggerGen(c =>
{// 允许Swagger在请求头中传递自定义头部信息c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme{In = ParameterLocation.Header,Description = "JWT Authorization header using the Bearer scheme.",Name = "Authorization",Type = SecuritySchemeType.ApiKey});c.AddSecurityRequirement(new OpenApiSecurityRequirement{{new OpenApiSecurityScheme{Reference = new OpenApiReference{Type = ReferenceType.SecurityScheme,Id = "Bearer"}},new string[] {}}});// 添加自定义头部c.OperationFilter<AddCustomHeaderOperationFilter>();
});public class AddCustomHeaderOperationFilter : IOperationFilter
{public void Apply(OpenApiOperation operation, OperationFilterContext context){// 添加自定义请求头operation.Parameters.Add(new OpenApiParameter{Name = "X-Custom-Header", // 自定义头的名称In = ParameterLocation.Header,Description = "This is a custom header for testing purposes.",Required = false // 设置为 false,如果是必需的可以设置为 true});}
}
正确的Authorization头部信息格式问题
通过查看服务器返回的信息:
发现我提交的格式有问题
www-authenticate: Bearer
以下是一个提交的示例请求,其中包含了自定义头部信息,注意Authorization的格式:
curl -X 'POST' \'https://localhost:7050/api/ideas' \-H 'accept: */*' \-H 'Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjEiLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoic3RyaW5nIiwiZXhwIjoxNzM0MjkxMjQxLCJpc3MiOiJ5b3VyX2lzc3Vlcl9oZXJlIiwiYXVkIjoieW91cl9hdWRpZW5jZV9oZXJlIn0.7G9yfuG_UGmP4r7gMvW7EzJ0QQGSRuhG-oWMgP6_5vE' \-H 'Content-Type: application/json' \-d '{"title": "string","description": "string"
}'
JWT失效问题
通过查看服务器返回的信息:
发现我提交的JWT Token已经失效
www-authenticate: Bearer error="invalid_token"
尝试不验证过期时间,但是依然失败。
我使用https://jwt.io/这个网站去验证了以下密钥,发现是有效的。
通过添加让服务器打印出验证错误日志的方法,发现还是格式问题。<>是占位符不是真实的内容。(上面示例已经被修改未正确格式)
修改后成功验证。
如何让服务器打印出验证错误日志:
添加potions.Events选项
//TODO: 查看思考以下这个打印设置的逻辑
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme).AddJwtBearer(options =>{// 使用对称密钥(例如 HS256)来验证 JWTvar key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["Jwt:SecretKey"]));options.TokenValidationParameters = new TokenValidationParameters{// 设置签名密钥IssuerSigningKey = key,ValidateIssuer = false, // 如果不验证发行者,可以设置为 falseValidateAudience = false, // 如果不验证受众,可以设置为 falseValidateLifetime = false, // 验证令牌过期时间ClockSkew = TimeSpan.Zero // 过期时间允许的时钟偏差};// 添加错误处理回调options.Events = new JwtBearerEvents{OnAuthenticationFailed = context =>{// 记录验证失败的错误信息context.NoResult();context.Response.Headers.Add("Token-Error", "Invalid Token");Console.WriteLine($"Authentication failed: {context.Exception.Message}");return Task.CompletedTask;},OnChallenge = context =>{// 记录挑战失败的错误信息Console.WriteLine($"Authentication challenge: {context.ErrorDescription}");return Task.CompletedTask;}};});
Post提交灵感API问题
//TODO: 未完成,待解决的Bug,需要先分析以下问题,bug日志如下
通过查看服务器返回的信息:
System.FormatException: The input string 'string' was not in a correct format.at System.Number.ThrowFormatException[TChar](ReadOnlySpan`1 value)at System.Int32.Parse(String s)at BrainStromAPIs.AppDatasEndpoints.<>c.<<RegisterAppDatasEndpoints>b__0_2>d.MoveNext() in E:\GanX\DotNetProject\BrainStromAPIs\BrainStromAPIs\AppData.cs:line 123
--- End of stack trace from previous location ---at Microsoft.AspNetCore.Http.RequestDelegateFactory.ExecuteTaskResult[T](Task`1 task, HttpContext httpContext)at Microsoft.AspNetCore.Http.RequestDelegateFactory.<>c__DisplayClass102_2.<<HandleRequestBodyAndCompileRequestDelegateForJson>b__2>d.MoveNext()
--- End of stack trace from previous location ---at Swashbuckle.AspNetCore.SwaggerUI.SwaggerUIMiddleware.Invoke(HttpContext httpContext)at Swashbuckle.AspNetCore.Swagger.SwaggerMiddleware.Invoke(HttpContext httpContext, ISwaggerProvider swaggerProvider)at Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddlewareImpl.Invoke(HttpContext context)HEADERS
=======
Accept: */*
Host: localhost:7050
User-Agent: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36 Edg/131.0.0.0
Accept-Encoding: gzip, deflate, br, zstd
Accept-Language: zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1laWRlbnRpZmllciI6IjEiLCJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoic3RyaW5nIiwiZXhwIjoxNzM0MjkxMjQxLCJpc3MiOiJ5b3VyX2lzc3Vlcl9oZXJlIiwiYXVkIjoieW91cl9hdWRpZW5jZV9oZXJlIn0.7G9yfuG_UGmP4r7gMvW7EzJ0QQGSRuhG-oWMgP6_5vE
Content-Type: application/json
Cookie: Rider-bcaa2264=df76c046-993f-4586-8adf-dc509c9b148f
Origin: https://localhost:7050
Referer: https://localhost:7050/swagger/index.html
Content-Length: 47
sec-ch-ua-platform: "Windows"
sec-ch-ua: "Microsoft Edge";v="131", "Chromium";v="131", "Not_A Brand";v="24"
sec-ch-ua-mobile: ?0
sec-fetch-site: same-origin
sec-fetch-mode: cors
sec-fetch-dest: empty
priority: u=1, i
相关文章:
【开发日志】ASP.NET Core Minimal APIs开发日志
后端 实现登录注册 注册API 在数据库中存储/注册账户密码 登录API 检测接收来的账户密码,如果正确,则生成JWT Token返回给客户端 未配置密钥 报错信息,这是我在提交注册请求时,后端报的错,看起来是在生成JWT Token时出现了…...
5G学习笔记之Non-Public Network R18
只是协议的搬运工 目录 0. NPN其它笔记 1. 概述 2. R18增强 2.1 等效SNPN间的移动性管理 2.2 non-3GPP接入SNPN 2.3 Localized Service 2.4 Charging 2.5 Management 0. NPN其它笔记 1. SNPN系列ID和广播消息 1. 概述 NPN,Non-Public Network, 非公共网络…...
sheng的学习笔记-AI-WaveNet模型
Ai目录:sheng的学习笔记-AI目录-CSDN博客 需要先看一下这些文章,作为基础 sheng的学习笔记-AI-残差网络-Residual Networks (ResNets)_神经网络的衰变是什么-CSDN博客 sheng的学习笔记-AI-卷积神经网络_单层卷积神经网络-CSDN博客 sheng的学习笔记-T…...
0002.基于springboot +layui二手物品交易平台
适合初学同学练手项目,部署简单,代码简洁清晰; 注:当前项目架构使用前后端未分离哦! 一、系统架构 前端:layui| html 后端:springboot | mybatis-plus 环境:jdk1.8 | mysql | maven 二、代…...
java集合基础
Java的java.util包主要提供了以下三种类型的集合: List:一种有序列表的集合,例如,按索引排列的Student的List;Set:一种保证没有重复元素的集合,例如,所有无重复名称的Student的Set&…...
如何在NGINX中实现基于IP的访问控制(IP黑白名单)?
大家好,我是锋哥。今天分享关于【如何在NGINX中实现基于IP的访问控制(IP黑白名单)?】面试题。希望对大家有帮助; 如何在NGINX中实现基于IP的访问控制(IP黑白名单)? 1000道 互联网大…...
「Mac玩转仓颉内测版51」基础篇13 - 高阶函数与闭包
本篇详细介绍高阶函数和闭包,这是仓颉语言中实现灵活逻辑的关键工具。高阶函数可将函数作为参数或返回值使用,而闭包能捕获其定义域中的变量,并在后续调用中保持状态。这些概念能让代码更加简洁、灵活,并提升复用性。 关键词 高阶…...
如何与GPT更高效的问答
与GPT进行高效沟通的关键在于提问的方式。通过合理的提问技巧,可以更清晰地表达需求,从而获得更准确的回答。以下是一些实用的建议,帮助你提升与GPT的交流效率。 1. 使用简单明了的语言: 尽量避免使用复杂的术语和行话,…...
【Android】解决 ADB 中 SELinux 设置与 `Failed transaction (2147483646)` 错误
解决 ADB 中 SELinux 设置与 Failed transaction (2147483646) 错误 在使用 ADB 进行开发和调试时,经常会遇到由于 Android 系统安全策略(SELinux)引起的权限问题,尤其是在执行某些操作时,可能会遇到类似 cmd: Failur…...
etcd常用监控
通过部署etcd-exporterPrometheus,然后配置etcd相关告警可以及时发现etcd集群风险 常见监控项目 1. etcd集群无leader Etcd cluster have no leader - alert:EtcdNoLeaderexpr: etcd_server_has_leader 0 for:0mlabels:severity: criticalannotations:summary:Et…...
红日靶场vulnstack 7靶机的测试报告[细节](一)
目录 一、测试环境 1、系统环境 2、注意事项 3、使用工具/软件 二、测试目的 三、操作过程 1、信息搜集 2、Redis未授权访问漏洞获取web1靶机系统权限 3、获取docker靶机系统权限 ①Laravel框架漏洞利用getshell ②Laravel主机的提权&&docker容器逃逸 提权…...
【计算机网络】Layer4-Transport layer
目录 传输层协议How demultiplexing works in transport layer(传输层如何进行分用)分用(Demultiplexing)的定义:TCP/UDP段格式: UDPUDP的特点:UDP Format端口号Trivial File Transfer Protocol…...
【conda/cuda/cudnn/tensorrt】一份简洁的深度学习环境安装清单
🚀本文主要总结一下conda、cuda、cudnn、tensorrt的快速安装。至于nvidia显卡驱动的安装,暂且不提。本文适合有一定反复安装经验的读者😂,方便其快速整理安装思路。 NVIDIA Drivers 🌔01conda ⭐️ 注意,c…...
在C语言中,访问结构体的成员时,什么时候用`.`【符号点】,什么时候用符号`->`?
在C语言中,访问结构体成员时,使用.和->的情况取决于你是否通过结构体指针来访问。 .(点运算符):当你有一个结构体变量时,使用点运算符来访问它的成员。例如: struct Person {char name[50];i…...
Java序列化
Java序列化 简单来说: 序列化是将对象的状态信息转换为可以存储或传输的形式(如字节序列)的过程。在 Java 中,通过序列化可以把一个对象保存到文件、通过网络传输到其他地方或者存储到数据库等。最直接的原因就是某些场景下需要…...
Python 方框消除小游戏
import pygame import random# 初始化pygame pygame.init()# 设置屏幕大小 screen pygame.display.set_mode((800, 600))# 设置标题 pygame.display.set_caption("打砖块")# 定义颜色 WHITE (255, 255, 255) BLACK (0, 0, 0) RED (255, 0, 0) GREEN (0, 255, 0)…...
微软 Phi-4:小型模型的推理能力大突破
在人工智能领域,语言模型的发展日新月异。微软作为行业的重要参与者,一直致力于推动语言模型技术的进步。近日,微软推出了最新的小型语言模型 Phi-4,这款模型以其卓越的复杂推理能力和在数学领域的出色表现,引起了广泛…...
OkHttp源码分析:分发器任务调配,拦截器责任链设计,连接池socket复用
目录 一,分发器和拦截器 二,分发器处理异步请求 1.分发器处理入口 2.分发器工作流程 3.分发器中的线程池设计 三,分发器处理同步请求 四,拦截器处理请求 1.责任链设计模式 2.拦截器工作原理 3.OkHttp五大拦截器 一&#…...
前后端跨域问题(CROS)
前端 在src中创建util文件,写request.js文件: request.js代码如下: import axios from axios import { ElMessage } from element-plus;const request axios.create({// baseURL: /api, // 注意!! 这里是全局统一加…...
ctfshow xss
1.web316 看的wp 先在服务器上写一个php文件 <?php$cookie $_GET[cookie];$time date(Y-m-d h:i:s, time());$log fopen("cookie.txt", "a");fwrite($log,$time.: . $cookie . "\n");fclose($log); ?> 获取cookie的值ÿ…...
kafka客户端调用
kafka客户端调用 springboot整合kafkajava调用kafka其他问题 springboot整合kafka 手动提交需要在配置文件配置kafka属性 kafka.listener.ack-mode: manual Component public class MyKafkaListener {Autowiredprivate SaslClient saslClient;//监听所有分区KafkaListener(top…...
Linux 中 sftp 命令基本使用
参考链接 sftp 命令_sftp命令-CSDN博客 登录服务器【必须】 # sftp userNamehost # 例如 sftp root8.138.86.224 上传文件到服务器 使用 sftp 命令可以将本地文件上传到远程主机 # put local_file remote_file # 例如: put E://1.mp4 /root/1.mp4 下载文件 使…...
xtu oj 3个矩形与1个正方形
文章目录 回顾前言代码思路 回顾 xtu oj 神经网络xtu oj 1167 逆序数(大数据)xtu oj 原根xtu oj 不定方程的正整数解xtu oj 最多的可变换字符串xtu oj String Ixtu oj 字母序列xtu oj 分段xtu oj 完全平方数IIxtu oj 连接字符串xtu oj 2021xtu oj 数字x…...
C++ 引用
引用(Reference)是C语言中用于给变量起别名的特性,是一种轻量级的变量访问方式。通过引用,可以对原变量进行操作而不需要直接访问原变量的内存地址。这一特性极大地增强了代码的简洁性和安全性,同时也在参数传递和返回…...
解决几个常见的ASP.NET Core Web API 中多线程并发写入数据库失败的问题
前言 在ASP.NET Core Web API应用程序中,当多个并发线程同时调用新增用户数据的接口时,可能会遇到数据库写入失败的问题。这个问题通常源于多个线程同时访问数据库时,可能会导致以下情况: 数据库连接池耗尽:每个线程…...
让知识更具生命力
在当今快速发展的技术世界中,技术文档的重要性不言而喻。它不仅是知识传递的有效载体,也是团队协作的基石,更是提升产品竞争力的重要工具。然而,编写出一份清晰、完整且实用的技术文档,对于许多开发者和团队来说并非易…...
批量DWG文件转dxf(CAD图转dxf)——c#插件实现
此插件可将指定文件夹及子文件夹下的dwg文件批量转为dxf文件。 (使用方法:命令行输入 “netload” 加载插件,然后输入“dwg2dxf”运行,选择文件夹即可。) 生成dxf在此新建的文件夹路径下,包含子文件夹内的…...
《Django 5 By Example》阅读笔记:p561-p613
《Django 5 By Example》学习第 21 天,p561-p613 总结,总计 53 页。 一、技术总结 1.mixins (1)定义(什么是 mixins?) p570,Mixins are a special kind of multiple inheritance for a class. (2)适用场景(为什么使用?) 1)…...
1. 字符串分割
给定一个非空字符串S,其被N个‘-’分隔成N1的子串,给定正整数K,要求除第一个子串外,其余的子串每K个字符组成新的子串,并用‘-’分隔。对于新组成的每一个子串,如果它含有的小写字母比大写字母多࿰…...
[SAP ABAP] 将内表数据转换为HTML格式
从sflight数据库表中检索航班信息,并将这些信息转换成HTML格式,然后下载或显示在前端 开发步骤 ① 自定义一个数据类型 ty_sflight 来存储航班信息 ② 声明内表和工作区变量,用于存储表头、字段、HTML内容和航班详细信息以及创建字段目录lt…...
计算机网络-应用层
应用层是咱们日常开发中,最常用到的一层 主要涉及到两种情况: 1.使用大佬们已经创建好的应用层协议(后面再讨论,应用层知名的协议有很多,其中的佼佼者就是 HTTP (后面会出单独的文章来讲解))2.自己定义应用…...
SpringEvent 解决 WebUploader 大文件上传解耦问题
一、SpringEvent涉及的相关组件 为了让不熟悉SpringEvent的朋友对Event也有一个大致的印象。这里还是对SpringEvent对象包含的方法和相关组件的应用进行简单的介绍。 1、 事件(Event) 事件是应用程序中发生的某种事情,可以是用户行为、系统…...
KALI安装操作及过程
以下是在计算机上安装 Kali Linux 的详细教程:(通常我直接使用虚拟机) 解压虚拟机安装包,直接在虚拟机中打开KALI (将内存改为4GB) 初始密码账号:kali 一、准备工作 下载 Kali Linux 镜像文件…...
Scala—“==“和“equals“用法(附与Java对比)
Scala 字符串比较—""和"equals"用法 Scala 的 在 Scala 中, 是一个方法调用,实际上等价于调用 equals 方法。不仅适用于字符串,还可以用于任何类型,并且自动处理 null。 Demo: Java 的 在 J…...
[Flutter] : Clipboard
import package:flutter/material.dart; import package:flutter/services.dart; setData Clipboard.setData(ClipboardData(text: "传入的文字内容")); getData Clipboard.getData(Clipboard.kTextPlain) 记录 | Flutter剪切板-刨根问底做一个可以在后台…...
vue2:v-for实现的el-radio-group选中时显示角标,并自定义选中按钮的字体颜色和背景色
项目中需要实现一组预定义查询,每一个查询按钮在选中时右上角显示一个角标,展示当前查询返回的数据条目。 1、text-color="#3785FF" fill="#E6EAF1" 处理选中时的字体颜色和背景色,如上图,分别为蓝色和浅灰色。 2、badge中:value="selectedRadio…...
Dynamics 365 CRM- 后端
Dynamics 365 CRM 后端插件语法示例 public IPluginExecutionContext context null;//上下文 public IOrganizationServiceFactory serviceFactory null;//组织服务工厂对象 public IOrganizationService service null;//Org服务对象//创建执行上下文 context (IPluginExe…...
电脑显示器选购指南2024
选择显示器是五花八门的显示参数,如何选择,以下给出参数说明,及部分参考: 1. 尺寸和分辨率 尺寸(英寸) 根据使用距离和用途选择合适的屏幕尺寸: 21-24 英寸:适合小桌面空间、日常…...
机器学习-多元线性回归
文章目录 代码什么是回归任务什么是多元什么是回归什么是多元线性回归表达式何时使用多元线性回归注意损失函数 代码 https://github.com/FULLK/AI_Study/tree/main/%E6%9C%BA%E5%99%A8%E5%AD%A6%E4%B9%A0-%E5%A4%9A%E5%85%83%E7%BA%BF%E6%80%A7%E5%9B%9E%E5%BD%92 什么是回归…...
WEB语义化的新探索:浅析LLMs.txt
【引】有人迷恋使用大模型生成各种有趣的内容, 有人沉醉于大模型相关技术的探索,没有对错,只在于你的乐趣所在。 一项名为 llms.txt 的新提案标志了一些非同寻常的东西的出现: 一个Web网站不仅为人类读者服务,而且为人工智能提供服…...
【经典】制造供应链四类策略(MTS、MTO、ATO、ETO)细说
关注作者 制造供应链的牛鞭问题与复杂问题主要是从两个方面解决,一是同步化供应链消减从需求到供应的放大效应,二是供应链细分,针对不同的客户、不同的需求供应的匹配策略来应对复杂性,更好的满足客户并以最低的总成本来实现。 对…...
RabbitMQ中的Publish-Subscribe模式
在现代分布式系统中,消息队列(Message Queue)是实现异步通信和解耦系统的关键组件。RabbitMQ 是一个功能强大且广泛使用的开源消息代理,支持多种消息传递模式。其中,Publish/Subscribe(发布/订阅࿰…...
简单了解一下 Go 语言的构建约束?
构建约束是一种在 Go 语言中控制源文件编译条件的方法,它可以让您指定某些文件只在特定的操作系统、架构、编译器或 Go 版本下编译,而在其他环境中自动忽略。这样可以方便您针对不同的平台或场景编写不同的代码,实现条件编译的功能。 构建…...
图像融合算法笔记2024 CDTNet
目录 ControlCom-Image-Composition CDTNet-High-Resolution-Image-Harmonization 依赖项: trilinear 效果图: 推理代码ok 只支持linux系统: ControlCom-Image-Composition CDTNet-High-Resolution-Image-Harmonization 开源地址: GitHub - bcmi/CDTNet-High-Reso…...
我们来对接蓝凌OA --报文格式
题记 数智化办公专家、国家高新技术企业、知识管理国家标准制定者、信创供应商10强…等等,这些和咱们有关系吗!!不好意思,走错片场了,刚和项目经理在甲方那边吹牛B想想刚刚的大饼,看看支付宝余额ÿ…...
npm、yarn、pnpm三者的异同
这个表格将会说明一切: 特性npmyarnpnpm依赖管理方式扁平化管理,嵌套依赖树,可能重复安装扁平化管理喝符号链接,同版本只能安装一次基于硬链接喝符号链接的内容寻址存储安装速度最慢中等(并行安装)最快(得益于硬链接的复用)磁盘空…...
纯CSS实现文本或表格特效(连续滚动与首尾相连)
纯CSS实现文本连续向左滚动首尾相连 1.效果图: 2.实现代码: <!DOCTYPE html> <html lang"en"><head><meta charset"UTF-8" /><meta name"viewport" content"widthdevice-width, init…...
信号处理:概念、技术、领域
目录 基本概念 主要技术 应用领域 信号处理是一个涉及分析、修改和再生信号的多学科领域。信号可以是各种形式的,例如声音、图像、视频或其他类型的监测数据。信号处理的主要目标是提取有用的信息并增强信号的质量。以下是信号处理的一些基本概念和应用ÿ…...
Android 中 Activity 和 Fragment 的结合使用经典案例
学习笔记 0. 分析 Activity 与 Fragment 的区别,部分使用的差异 上一篇中我们分析了Activity 与 Fragment 的区别,部分使用的差异。 点我跳转上一篇 1. 单个 Activity 中使用多个 Fragment 这是最常见的用法之一,特别是在单屏幕应用中。通…...
Http协议在网站中的体现
文章目录 1. Http协议简介2. 网站中的体现2.1 访问网站2.2 请求2.3 请求头2.4 请求方式2.5 响应 3. 总结 1. Http协议简介 HTTP(超文本传输协议) 是一种广泛应用于互联网上的应用层协议,用于在Web浏览器和Web服务器之间传输数据。HTTP协议定…...