|
|
|
@ -1,4 +1,6 @@
|
|
|
|
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|
|
|
|
using System.Globalization;
|
|
|
|
|
using System.Threading.RateLimiting;
|
|
|
|
|
using Microsoft.AspNetCore.Authentication.JwtBearer;
|
|
|
|
|
using Microsoft.AspNetCore.Cors;
|
|
|
|
|
using Microsoft.OpenApi.Models;
|
|
|
|
|
using Newtonsoft.Json.Converters;
|
|
|
|
@ -10,6 +12,7 @@ using NPin.Framework.AspNetCore.Authentication.OAuth.QQ;
|
|
|
|
|
using NPin.Framework.AspNetCore.Microsoft.AspNetCore.Builder;
|
|
|
|
|
using NPin.Framework.AspNetCore.Microsoft.Extensions.DependencyInjection;
|
|
|
|
|
using NPin.Framework.TenantManagement.Application;
|
|
|
|
|
using NPin.Framework.Upms.Application;
|
|
|
|
|
using NPin.SqlSugarCore;
|
|
|
|
|
using Volo.Abp.AspNetCore.Authentication.JwtBearer;
|
|
|
|
|
using Volo.Abp.AspNetCore.MultiTenancy;
|
|
|
|
@ -63,9 +66,14 @@ public class NPinWebModule : AbpModule
|
|
|
|
|
opt.ConventionalControllers.Create(typeof(NPinApplicationModule).Assembly,
|
|
|
|
|
opts => opts.RemoteServiceName = "default");
|
|
|
|
|
// TODO 添加其它模块的动态API
|
|
|
|
|
// TODO Rbac bbs code-gen
|
|
|
|
|
// TODO bbs code-gen
|
|
|
|
|
opt.ConventionalControllers.Create(typeof(NPinFrameworkUpmsApplicationModule).Assembly,
|
|
|
|
|
opts => opts.RemoteServiceName = "upms");
|
|
|
|
|
opt.ConventionalControllers.Create(typeof(NPinFrameworkTenantManagementApplicationModule).Assembly,
|
|
|
|
|
opts => opts.RemoteServiceName = "tenant-management");
|
|
|
|
|
|
|
|
|
|
// 统一API前缀
|
|
|
|
|
opt.ConventionalControllers.ConventionalControllerSettings.ForEach(x => x.RootPath = "api");
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// Api格式配置
|
|
|
|
@ -126,6 +134,40 @@ public class NPinWebModule : AbpModule
|
|
|
|
|
opt.TenantResolvers.Add(new HeaderTenantResolveContributor());
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
//速率限制
|
|
|
|
|
//每60秒限制100个请求,滑块添加,分6段
|
|
|
|
|
context.Services.AddRateLimiter(opt =>
|
|
|
|
|
{
|
|
|
|
|
opt.RejectionStatusCode = StatusCodes.Status429TooManyRequests;
|
|
|
|
|
opt.OnRejected = (ctx, _) =>
|
|
|
|
|
{
|
|
|
|
|
if (ctx.Lease.TryGetMetadata(MetadataName.RetryAfter, out var retryAfter))
|
|
|
|
|
{
|
|
|
|
|
ctx.HttpContext.Response.Headers.RetryAfter =
|
|
|
|
|
((int)retryAfter.TotalSeconds).ToString(NumberFormatInfo.InvariantInfo);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ctx.HttpContext.Response.StatusCode = StatusCodes.Status429TooManyRequests;
|
|
|
|
|
ctx.HttpContext.Response.WriteAsync("太多请求了,请稍后再试。");
|
|
|
|
|
return new ValueTask();
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// 全局使用,链式表达式
|
|
|
|
|
opt.GlobalLimiter = PartitionedRateLimiter.CreateChained(PartitionedRateLimiter.Create<HttpContext, string>(
|
|
|
|
|
httpContext =>
|
|
|
|
|
{
|
|
|
|
|
var userAgent = httpContext.Request.Headers.UserAgent.ToString();
|
|
|
|
|
return RateLimitPartition.GetSlidingWindowLimiter(userAgent, _ =>
|
|
|
|
|
new SlidingWindowRateLimiterOptions
|
|
|
|
|
{
|
|
|
|
|
PermitLimit = 1000,
|
|
|
|
|
Window = TimeSpan.FromSeconds(60),
|
|
|
|
|
SegmentsPerWindow = 6,
|
|
|
|
|
QueueProcessingOrder = QueueProcessingOrder.OldestFirst
|
|
|
|
|
});
|
|
|
|
|
}));
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
// 配置 JWT 鉴权
|
|
|
|
|
// var jwtOptions = configuration.GetSection(nameof(JwtOptions))
|
|
|
|
|
|
|
|
|
|