【开发日志】ASP.NET Core Minimal APIs开发日志

后端

实现登录注册

注册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 26
   at 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

发现在生成时,调用了配置文件,但是我却没有正确的配置密钥,导致了这个问题。

csharp 复制代码
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:SecretKey"]));

通过在appsettings.json中添加密钥配置,解决了这个问题。

json 复制代码
  "Jwt": {
    "SecretKey": "your_secret_key_here"
  }
密钥长度不足

报错信息,这是在注册API中,生成JWT Token时出现的异常,看起来是密钥长度不足导致的问题。

shell 复制代码
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 36
   at 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位。

json 复制代码
    "Jwt": {
    "SecretKey": "your_32_byte_secret_key_here_XGanQAQ"
  }

灵感的CRUD操作

身份验证的配置问题

由于我没有正确的配置身份验证,导致了这个问题。

空的配置

csharp 复制代码
builder.Services.AddAuthentication();

因为我采用的是JWT Token的身份验证方式,所以需要在配置中添加JWT Token的验证方式。

由因为我是在服务端通过使用对称密钥(HS256 算法)来签发/生成的 JWT,所以配置如下:

csharp 复制代码
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        // 使用对称密钥(例如 HS256)来验证 JWT
        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["Jwt:SecretKey"]));

        options.TokenValidationParameters = new TokenValidationParameters
        {
            // 设置签名密钥
            IssuerSigningKey = key,
            ValidateIssuer = false,  // 如果不验证发行者,可以设置为 false
            ValidateAudience = false,  // 如果不验证受众,可以设置为 false
            ValidateLifetime = true,  // 验证令牌过期时间
            ClockSkew = TimeSpan.Zero  // 过期时间允许的时钟偏差
        };
    });
Swagger如何配置身份验证密钥问题

首先,你需要在 Swagger 配置中告诉它允许传递额外的请求头。这可以通过在 Program.cs 或 Startup.cs 文件中配置 SwaggerGen 来完成。

假设你要为所有 API 添加一个名为 X-Custom-Header 的自定义头,步骤如下:

csharp 复制代码
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头部信息格式问题

通过查看服务器返回的信息:

发现我提交的格式有问题

shell 复制代码
www-authenticate: Bearer 

以下是一个提交的示例请求,其中包含了自定义头部信息,注意Authorization的格式:

shell 复制代码
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已经失效

shell 复制代码
www-authenticate: Bearer error="invalid_token"

尝试不验证过期时间,但是依然失败。

我使用https://jwt.io/这个网站去验证了以下密钥,发现是有效的。

通过添加让服务器打印出验证错误日志的方法,发现还是格式问题。<>是占位符不是真实的内容。(上面示例已经被修改未正确格式)

修改后成功验证。

如何让服务器打印出验证错误日志:

添加potions.Events选项

//TODO: 查看思考以下这个打印设置的逻辑

csharp 复制代码
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        // 使用对称密钥(例如 HS256)来验证 JWT
        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["Jwt:SecretKey"]));

        options.TokenValidationParameters = new TokenValidationParameters
        {
            // 设置签名密钥
            IssuerSigningKey = key,
            ValidateIssuer = false,  // 如果不验证发行者,可以设置为 false
            ValidateAudience = false,  // 如果不验证受众,可以设置为 false
            ValidateLifetime = 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日志如下

通过查看服务器返回的信息:

shell 复制代码
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 26
   at 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

发现在生成时,调用了配置文件,但是我却没有正确的配置密钥,导致了这个问题。

csharp 复制代码
var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["Jwt:SecretKey"]));

通过在appsettings.json中添加密钥配置,解决了这个问题。

json 复制代码
  "Jwt": {
    "SecretKey": "your_secret_key_here"
  }
密钥长度不足

报错信息,这是在注册API中,生成JWT Token时出现的异常,看起来是密钥长度不足导致的问题。

shell 复制代码
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 36
   at 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位。

json 复制代码
    "Jwt": {
    "SecretKey": "your_32_byte_secret_key_here_XGanQAQ"
  }

灵感的CRUD操作

身份验证的配置问题

由于我没有正确的配置身份验证,导致了这个问题。

空的配置

csharp 复制代码
builder.Services.AddAuthentication();

因为我采用的是JWT Token的身份验证方式,所以需要在配置中添加JWT Token的验证方式。

由因为我是在服务端通过使用对称密钥(HS256 算法)来签发/生成的 JWT,所以配置如下:

csharp 复制代码
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        // 使用对称密钥(例如 HS256)来验证 JWT
        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["Jwt:SecretKey"]));

        options.TokenValidationParameters = new TokenValidationParameters
        {
            // 设置签名密钥
            IssuerSigningKey = key,
            ValidateIssuer = false,  // 如果不验证发行者,可以设置为 false
            ValidateAudience = false,  // 如果不验证受众,可以设置为 false
            ValidateLifetime = true,  // 验证令牌过期时间
            ClockSkew = TimeSpan.Zero  // 过期时间允许的时钟偏差
        };
    });
Swagger如何配置身份验证密钥问题

首先,你需要在 Swagger 配置中告诉它允许传递额外的请求头。这可以通过在 Program.cs 或 Startup.cs 文件中配置 SwaggerGen 来完成。

假设你要为所有 API 添加一个名为 X-Custom-Header 的自定义头,步骤如下:

csharp 复制代码
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头部信息格式问题

通过查看服务器返回的信息:

发现我提交的格式有问题

shell 复制代码
www-authenticate: Bearer 

以下是一个提交的示例请求,其中包含了自定义头部信息,注意Authorization的格式:

shell 复制代码
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已经失效

shell 复制代码
www-authenticate: Bearer error="invalid_token"

尝试不验证过期时间,但是依然失败。

我使用https://jwt.io/这个网站去验证了以下密钥,发现是有效的。

通过添加让服务器打印出验证错误日志的方法,发现还是格式问题。<>是占位符不是真实的内容。(上面示例已经被修改未正确格式)

修改后成功验证。

如何让服务器打印出验证错误日志:

添加potions.Events选项

//TODO: 查看思考以下这个打印设置的逻辑

csharp 复制代码
builder.Services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
    .AddJwtBearer(options =>
    {
        // 使用对称密钥(例如 HS256)来验证 JWT
        var key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(configuration["Jwt:SecretKey"]));

        options.TokenValidationParameters = new TokenValidationParameters
        {
            // 设置签名密钥
            IssuerSigningKey = key,
            ValidateIssuer = false,  // 如果不验证发行者,可以设置为 false
            ValidateAudience = false,  // 如果不验证受众,可以设置为 false
            ValidateLifetime = 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日志如下

通过查看服务器返回的信息:

shell 复制代码
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
相关推荐
bing_1582 小时前
简单工厂模式 (Simple Factory Pattern) 在Spring Boot 中的应用
spring boot·后端·简单工厂模式
天上掉下来个程小白2 小时前
案例-14.文件上传-简介
数据库·spring boot·后端·mybatis·状态模式
Asthenia04123 小时前
基于Jackson注解的JSON工具封装与Redis集成实战
后端
编程星空3 小时前
css主题色修改后会多出一个css吗?css怎么定义变量?
开发语言·后端·rust
程序员侠客行4 小时前
Spring事务原理 二
java·后端·spring
dmy4 小时前
docker 快速构建开发环境
后端·docker·容器
sjsjsbbsbsn5 小时前
Spring Boot定时任务原理
java·spring boot·后端
计算机毕设指导65 小时前
基于Springboot学生宿舍水电信息管理系统【附源码】
java·spring boot·后端·mysql·spring·tomcat·maven
计算机-秋大田5 小时前
基于Spring Boot的兴顺物流管理系统设计与实现(LW+源码+讲解)
java·vue.js·spring boot·后端·spring·课程设计
羊小猪~~7 小时前
MYSQL学习笔记(九):MYSQL表的“增删改查”
数据库·笔记·后端·sql·学习·mysql·考研