【开发日志】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
相关推荐
Libby博仙1 小时前
asp.net core mvc的 ViewBag 和 ViewData 和 Module
后端·asp.net·mvc
Libby博仙1 小时前
创建.net core 8.0项目时,有个启用原生AOT发布是什么意思
microsoft·asp.net·.netcore
.生产的驴1 小时前
Elasticsearch 文档批处理 混合处理 批量操作
大数据·后端·elasticsearch·搜索引擎·微信小程序·全文检索·jenkins
JINGWHALE12 小时前
设计模式 结构型 代理模式(Proxy Pattern)与 常见技术框架应用 解析
前端·人工智能·后端·设计模式·性能优化·系统架构·代理模式
蒜蓉大猩猩2 小时前
Node.js - 文件操作
javascript·后端·sql·node.js
ccmjga2 小时前
Spring Boot 3 配置大全系列 —— 如何配置用户的登录与认证?
java·数据库·spring boot·后端·spring·单元测试·gradle
风月歌3 小时前
基于Spring Boot的IT技术交流和分享平台的设计与实现源码
java·spring boot·后端
想要打 Acm 的小周同学呀3 小时前
SpringBoot框架开发中常用的注解
java·spring boot·后端·项目开发
TPBoreas4 小时前
Spring Boot 内置工具类
java·spring boot·后端
绝无仅有4 小时前
用gozero实现教务crm系统中通用的在职继承和离职交接功能
后端·面试·架构