因为后面大约会做到EAI同步数据,就想现在本地电脑上先试试。

这里请求端,服务端,Token的生成、获取、验证,请求发送都是在本地本项目中完成。

  1. 作为服务端Token生成,在启动类中配置一个请求,用于用户生成并获取Token。这里就是获取请求时携带的用户名,配合配置文件里面的密钥等信息,生成的一个Token。再配置一个有效期。
    // 生成Token的端点
    app.MapPost("/AA/GetToken", (LoginRequest request) => {
        // 实际项目应在此处验证用户名密码
        var claims = new[] {
            new Claim(ClaimTypes.Name, request.Email),
            new Claim(JwtRegisteredClaimNames.Sub, request.Email),
            new Claim(JwtRegisteredClaimNames.Jti, Guid.NewGuid().ToString())
        };
    
        var key = new SymmetricSecurityKey(
            Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]));
        var creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
    
        var token = new JwtSecurityToken(
            issuer: builder.Configuration["Jwt:Issuer"],//(签发者)用于标识Token的发行方,一般是基础网址
            audience: builder.Configuration["Jwt:Audience"],//受众,与Issuer构成双重验证
            claims: claims,//身份认证的数据
            expires: DateTime.Now.AddMinutes(30),//token 有效期
            signingCredentials: creds);//创建对称加密密钥,绑定加密算法
    
        return Results.Ok(new
        {
            token = new JwtSecurityTokenHandler().WriteToken(token)
        });
    });
    
    app.UseAuthentication();
    app.UseAuthorization();

  2. 以上里面用到的配置文件项,在appsettings.json中。
    {
      "Jwt": {
        "Key": "YourSuperSecretKeyWith32Characters",
        "Issuer": "https://localhost:7093",
        "Audience": "MES"
      },
      "ConnectionStrings": {
        "HangfireConnection": "server=localhost;user=root;password=admin;database=test;Allow User Variables=True"
      },
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft.AspNetCore": "Warning"
        }
      },
      "AllowedHosts": "*"
    }

  3. 然后在Program.cs配置下Swagger,因为每次请求都手动配置Token到请求头里面会比较麻烦,所以这里配置后,每个请求就会自动携带Token。
    builder.Services.AddSwaggerGen(c => {
        c.SwaggerDoc("v1", new() { Title = "JWT Auth API", Version = "v1" });
    
        // JWT Bearer认证配置
        c.AddSecurityDefinition("Bearer", new OpenApiSecurityScheme
        {
            Description = "JWT Authorization头使用Bearer scheme. 格式: \"Bearer token\"",
            Name = "Authorization",
            In = ParameterLocation.Header,
            Type = SecuritySchemeType.ApiKey,
            Scheme = "Bearer"
        });
    
        c.AddSecurityRequirement(new OpenApiSecurityRequirement {
            {
                new OpenApiSecurityScheme {
                    Reference = new OpenApiReference {
                        Type = ReferenceType.SecurityScheme,
                        Id = "Bearer"
                    }
                },
                Array.Empty<string>()
            }
        });
    });

  4. 看下效果这里配置Token这里获取Token,注意配置Token的格式,有空格,没有{},eg:Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiamlhbmciLCJzdWIiOiJqaWFuZyIsImp0aSI6IjMxNWQwOWY0LTE2ODAtNGQwOC04M2ZhLTcwMzhmM2MyZjY4OSIsImV4cCI6MTc1NzM4OTcxMywiaXNzIjoiaHR0cHM6Ly9sb2NhbGhvc3Q6NzA5MyIsImF1ZCI6Ik1FUyJ9.GSK1Qd8v0Rxbep5EU3gSkeLxxrG8yYHTNhLA3NNwvxM
  5. 调试模式能看到Header里面的Authorization里面的配置Token
  6. 还有Controller里面要写Authorize注解,不然不生效
  7. 然后就是验证Token,这里有自动验证的配置,还写了一个主动验证的,好像没用上
    // 配置JWT认证 JWT配置注入 验证token用
    builder.Services.AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
    }).AddJwtBearer(options =>
    {
        options.TokenValidationParameters = new TokenValidationParameters
        {
            ValidateIssuer = true,
            ValidateAudience = true,
            ValidateLifetime = true,
            ValidateIssuerSigningKey = true,
            ClockSkew = TimeSpan.Zero, // 消除时钟偏移
            ValidIssuer = builder.Configuration["Jwt:Issuer"],
            ValidAudience = builder.Configuration["Jwt:Audience"],
            IssuerSigningKey = new SymmetricSecurityKey(
                Encoding.UTF8.GetBytes(builder.Configuration["Jwt:Key"]))
        };
    });

  8. 这里是Controller转别的请求,预计后面请求EAI的开放接口就可从这里发起,具体的参数传递,数据接收解析存储,后面再说吧。
    //https://localhost:7093/AA
    [HttpPost(Name = "Index")]
    public async Task<ActionResult> IndexAsync()
    {
        try
        {
           /* User user = new User();
            user.UserNo = "1";
            user.UserID = "001";
            user.Name = "AA";*/
            _httpClient = _factory.CreateClient("MyClient");
            //手动获取请求里面的token,放入新的请求头里面
            var token = HttpContext.Request.Headers["Authorization"].FirstOrDefault()?.Split(' ').Last();
            var tokenClient = new TokenHttpClient(_httpClient, token);
            var response = await tokenClient.SendRequestWithTokenAsync(
                "https://localhost:7093/AA/GetDetail",
                HttpMethod.Post);
            //var response = await JsonSender.PostJsonAsync(token,
            //    "AA/GetDetail",
            //    user);
            Console.WriteLine($"响应内容: {response}");
            return Ok(response);
            //return new ApiResponse<object> { Success = true, Data = response };
        }
        catch (Exception ex)
        {
            return new ApiResponse<object> { Success = false, Message = ex.Message };
        }
    }

  9. 效果,附测试代码

Logo

一座年轻的奋斗人之城,一个温馨的开发者之家。在这里,代码改变人生,开发创造未来!

更多推荐