using Apimanager_backend.Config; using Apimanager_backend.Data; using Apimanager_backend.Dtos; using Apimanager_backend.Filters; using Apimanager_backend.Filters.ExceptionFilter; using Apimanager_backend.Services; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.FileProviders; using Serilog; using Serilog.Sinks.MariaDB.Extensions; var builder = WebApplication.CreateBuilder(args); // Add services to the container. IConfiguration configuration = new ConfigurationBuilder() .SetBasePath(Directory.GetCurrentDirectory()) .AddJsonFile("appsettings.json", optional: false, reloadOnChange: true) .Build(); string? redStr = configuration["Redis:ConnectionString"]; string? constr = configuration.GetConnectionString("DefaultConnection"); //日志服务 /* Log.Logger = new LoggerConfiguration() .MinimumLevel.Debug() .WriteTo.Console() .WriteTo.MariaDB( connectionString: constr, tableName: "Logs", autoCreateTable:true ).CreateLogger(); builder.Host.UseSerilog(); */ builder.Services.AddDbContext(option => option.UseMySql(constr, MySqlServerVersion.AutoDetect(constr)) ); builder.Services.AddAllService(configuration); builder.Services.AddControllers(options => { //模型验证 options.Filters.Add(); //Exception过滤器 options.Filters.Add(); }).ConfigureApiBehaviorOptions(option => { option.SuppressModelStateInvalidFilter = true; }) .AddJsonOptions(options => { options.JsonSerializerOptions.MaxDepth = 64; }); // Learn more about configuring Swagger/OpenAPI at https://aka.ms/aspnetcore/swashbuckle builder.Services.AddEndpointsApiExplorer(); builder.Services.AddSwaggerGen(); var app = builder.Build(); app.Use(async (ctx, next) => { var controller = ctx.Request.RouteValues["controller"]?.ToString(); // YourController var action = ctx.Request.RouteValues["action"]?.ToString(); if (controller != "Public" || action != "Invoke") { await next(); return; } if (ctx.Request.Headers.TryGetValue("Authorization", out var hdr) && hdr.ToString().StartsWith("Bearer ")) { var token = hdr.ToString().Substring("Bearer ".Length).Trim(); var code = ctx.Request.RouteValues["code"]!.ToString()!; RateLimiterDto rateLimiterDto = new RateLimiterDto(); var userService = ctx.RequestServices.GetRequiredService(); var apiService = ctx.RequestServices.GetRequiredService(); var apiPackageItemService = ctx.RequestServices.GetRequiredService(); var userPackageService = ctx.RequestServices.GetRequiredService(); var user = await userService.GetByTokenAsync(token); var api = await apiService.GetApiInfoByEndpointAsync(code); var apiPackages = await apiPackageItemService.GetApiPackageItemsByApiIdAsync(api.Id); if (user == null || apiPackages.Count == 0) { ctx.Items["rateLimit"] = null; } else { var userPackages = await userPackageService.GetUserPackagesByUserIdAsync(user.Id); if (userPackages.Count == 0) { ctx.Items["rateLimit"] = null; } // 提取 list2 中的所有 package.id,变成 HashSet 提高查找效率 var apipackage1 = new HashSet(apiPackages.Select(x => x.ApiPackage.Id)); var uPackages = userPackages .Where(x => apipackage1.Contains(x.Package.Id)).ToList(); // 从 list1 中筛选出 user.id 存在于 list2 的项 var commonPackages = uPackages .Select(x => x.Package) .ToList(); var package = commonPackages.Count > 0 ? commonPackages.MaxBy(x => x.OneMinuteLimit) : null; var data = package == null ? null : new RateLimiterDto() { UserId = user.Id, RateLimit = package.OneMinuteLimit }; ctx.Items["rateLimit"] = data; ctx.Items["userPackages"] = uPackages; } } else { ctx.Items["rateLimit"] = null; } if (ctx.Items["rateLimit"] == null) { ctx.Response.StatusCode = 429; ctx.Response.ContentType = "application/json"; await ctx.Response.WriteAsJsonAsync(new ResponseBase() { Code = 3003, Data = null, Message = "未授权或访问频率受限" }); return; // ⛔ 不调用 next(),请求终止 } await next(); return; }); // Configure the HTTP request pipeline. if (app.Environment.IsDevelopment()) { app.UseSwagger(); app.UseSwaggerUI(); } //app.UseHttpsRedirection(); app.UseCors("AllowAll"); app.UseAuthentication(); app.UseAuthorization(); app.UseRateLimiter(); /* app.Use(async (context, next) => { var controller = context.Request.RouteValues["controller"]?.ToString(); // YourController var action = context.Request.RouteValues["action"]?.ToString(); // Invoke var code = context.Request.RouteValues["code"]?.ToString(); // ← 就是你要的 GetUserList Console.WriteLine($"控制器: {controller}, 实际方法: {code}(映射到 Invoke)"); // 你可以根据 code 设置速率限制策略、权限校验等 await next(); }); */ app.UseStaticFiles(new StaticFileOptions { FileProvider = new PhysicalFileProvider( Path.Combine(Directory.GetCurrentDirectory(), "uploads")), RequestPath = "/uploads" }); app.MapControllers(); app.Run();