【开发日志】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
相关推荐
努力的小郑1 小时前
Canal 不难,难的是用好:从接入到治理
后端·mysql·性能优化
Victor3562 小时前
MongoDB(87)如何使用GridFS?
后端
Victor3562 小时前
MongoDB(88)如何进行数据迁移?
后端
小红的布丁2 小时前
单线程 Redis 的高性能之道
redis·后端
GetcharZp2 小时前
Go 语言只能写后端?这款 2D 游戏引擎刷新你的认知!
后端
宁瑶琴4 小时前
COBOL语言的云计算
开发语言·后端·golang
普通网友4 小时前
阿里云国际版服务器,真的是学生党的性价比之选吗?
后端·python·阿里云·flask·云计算
IT_陈寒5 小时前
Vue的这个响应式问题,坑了我整整两小时
前端·人工智能·后端
Soofjan5 小时前
Go 内存回收-GC 源码1-触发与阶段
后端
shining6 小时前
[Golang]Eino探索之旅-初窥门径
后端