feat: 新增请求访问统计功能
This commit is contained in:
@@ -0,0 +1,12 @@
|
|||||||
|
using Microsoft.AspNetCore.Builder;
|
||||||
|
|
||||||
|
namespace Yi.Framework.Bbs.Application.Extensions;
|
||||||
|
|
||||||
|
public static class AccessLogExtensions
|
||||||
|
{
|
||||||
|
public static IApplicationBuilder UseAccessLog(this IApplicationBuilder app)
|
||||||
|
{
|
||||||
|
app.UseMiddleware<AccessLogMiddleware>();
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
using Microsoft.AspNetCore.Http;
|
||||||
|
using Volo.Abp.Caching;
|
||||||
|
using Volo.Abp.DependencyInjection;
|
||||||
|
using Yi.Framework.Bbs.Domain.Entities;
|
||||||
|
using Yi.Framework.Bbs.Domain.Shared.Caches;
|
||||||
|
using Yi.Framework.Bbs.Domain.Shared.Enums;
|
||||||
|
using Yi.Framework.SqlSugarCore.Abstractions;
|
||||||
|
|
||||||
|
namespace Yi.Framework.Bbs.Application.Extensions;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 访问日志中间件
|
||||||
|
/// 并发最高,采用缓存,默认10分钟才会真正操作一次数据库
|
||||||
|
///
|
||||||
|
/// 需考虑一致性问题,又不能上锁影响性能
|
||||||
|
/// </summary>
|
||||||
|
public class AccessLogMiddleware : IMiddleware, ITransientDependency
|
||||||
|
{
|
||||||
|
private readonly IDistributedCache<AccessLogCacheItem> _accessLogCache;
|
||||||
|
private readonly ISqlSugarRepository<AccessLogAggregateRoot> _repository;
|
||||||
|
|
||||||
|
public AccessLogMiddleware(IDistributedCache<AccessLogCacheItem> accessLogCache,
|
||||||
|
ISqlSugarRepository<AccessLogAggregateRoot> repository)
|
||||||
|
{
|
||||||
|
_accessLogCache = accessLogCache;
|
||||||
|
_repository = repository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public async Task InvokeAsync(HttpContext context, RequestDelegate next)
|
||||||
|
{
|
||||||
|
await next(context);
|
||||||
|
|
||||||
|
//获取缓存
|
||||||
|
var cache = await _accessLogCache.GetAsync(AccessLogCacheConst.Key);
|
||||||
|
|
||||||
|
//当前缓存需赋的值
|
||||||
|
long currentNumber = 1;
|
||||||
|
//最后插入的时间
|
||||||
|
DateTime lastInsertTime = DateTime.Now;
|
||||||
|
//cahce是空,创建缓存,当前数量从数据库中获取
|
||||||
|
//不等于空,如果大于当前天,插入数据库(间隔超过10分钟,也插入)
|
||||||
|
|
||||||
|
//获取当前访问数量
|
||||||
|
//没有缓存
|
||||||
|
if (cache is null)
|
||||||
|
{
|
||||||
|
//获取数据库今天最后最后一条数据
|
||||||
|
var currentDayEntity = await GetDateAccessLogEntityAsync();
|
||||||
|
|
||||||
|
//数据库有数据,以数据库数据为准+1
|
||||||
|
if (currentDayEntity is not null)
|
||||||
|
{
|
||||||
|
currentNumber = currentDayEntity.Number + 1;
|
||||||
|
}
|
||||||
|
//数据库没有数据,就是默认的1,重新开始
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//有缓存,根据根据缓存的值来
|
||||||
|
currentNumber = cache.Number + 1;
|
||||||
|
lastInsertTime = cache.LastInsertTime;
|
||||||
|
|
||||||
|
//数据库持久化
|
||||||
|
//缓存的日期大于当天的日期,插入到数据库,同时缓存变成0,重新开始统计
|
||||||
|
if (cache.LastModificationTime.Date > DateTime.Today)
|
||||||
|
{
|
||||||
|
await _repository.InsertAsync(new AccessLogAggregateRoot()
|
||||||
|
{ AccessLogType = AccessLogTypeEnum.Request, Number = currentNumber });
|
||||||
|
currentNumber = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (cache.LastInsertTime <= DateTime.Now - TimeSpan.FromMinutes(10))
|
||||||
|
{
|
||||||
|
//这里还需要判断数据库是否有值,不能之间更新
|
||||||
|
|
||||||
|
//缓存的时间大于当前数据库时间10分钟之后,更新(减少数据库交互,10分钟才更新一次)
|
||||||
|
var currentDayEntity = await GetDateAccessLogEntityAsync();
|
||||||
|
if (currentDayEntity is null)
|
||||||
|
{
|
||||||
|
await _repository.InsertAsync(new AccessLogAggregateRoot()
|
||||||
|
{ AccessLogType = AccessLogTypeEnum.Request, Number = currentNumber });
|
||||||
|
}
|
||||||
|
await _repository.UpdateAsync(currentDayEntity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//覆盖缓存
|
||||||
|
var newCache = new AccessLogCacheItem(currentNumber) { LastInsertTime = lastInsertTime };
|
||||||
|
await _accessLogCache.SetAsync(AccessLogCacheConst.Key, newCache);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 获取今天的统计
|
||||||
|
/// </summary>
|
||||||
|
/// <returns></returns>
|
||||||
|
private async Task<AccessLogAggregateRoot?> GetDateAccessLogEntityAsync()
|
||||||
|
{
|
||||||
|
//获取数据库今天最后最后一条数据
|
||||||
|
var currentDayEntity = await _repository._DbQueryable
|
||||||
|
.Where(x => x.AccessLogType == AccessLogTypeEnum.Request)
|
||||||
|
.Where(x => x.CreationTime == DateTime.Today)
|
||||||
|
.OrderByDescending(x => x.CreationTime)
|
||||||
|
.FirstAsync();
|
||||||
|
return currentDayEntity;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ using Volo.Abp.Application.Services;
|
|||||||
using Yi.Framework.Bbs.Application.Contracts.Dtos.AccessLog;
|
using Yi.Framework.Bbs.Application.Contracts.Dtos.AccessLog;
|
||||||
using Yi.Framework.Bbs.Application.Contracts.IServices;
|
using Yi.Framework.Bbs.Application.Contracts.IServices;
|
||||||
using Yi.Framework.Bbs.Domain.Entities;
|
using Yi.Framework.Bbs.Domain.Entities;
|
||||||
|
using Yi.Framework.Bbs.Domain.Shared.Enums;
|
||||||
using Yi.Framework.SqlSugarCore.Abstractions;
|
using Yi.Framework.SqlSugarCore.Abstractions;
|
||||||
|
|
||||||
namespace Yi.Framework.Bbs.Application.Services
|
namespace Yi.Framework.Bbs.Application.Services
|
||||||
@@ -11,7 +12,11 @@ namespace Yi.Framework.Bbs.Application.Services
|
|||||||
public class AccessLogService : ApplicationService, IAccessLogService
|
public class AccessLogService : ApplicationService, IAccessLogService
|
||||||
{
|
{
|
||||||
private readonly ISqlSugarRepository<AccessLogAggregateRoot> _repository;
|
private readonly ISqlSugarRepository<AccessLogAggregateRoot> _repository;
|
||||||
public AccessLogService(ISqlSugarRepository<AccessLogAggregateRoot> repository) { _repository = repository; }
|
|
||||||
|
public AccessLogService(ISqlSugarRepository<AccessLogAggregateRoot> repository)
|
||||||
|
{
|
||||||
|
_repository = repository;
|
||||||
|
}
|
||||||
|
|
||||||
public DateTime GetWeekFirst()
|
public DateTime GetWeekFirst()
|
||||||
{
|
{
|
||||||
@@ -45,16 +50,15 @@ namespace Yi.Framework.Bbs.Application.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取全部访问流量(3个月)
|
/// 获取全部访问流量(3个月)
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
/// <param name="AccessLogType"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<List<AccessLogDto>> Get()
|
public async Task<List<AccessLogDto>> GetListAsync([FromQuery] AccessLogTypeEnum AccessLogType)
|
||||||
{
|
{
|
||||||
var entities = await _repository._DbQueryable
|
var entities = await _repository._DbQueryable.Where(x => x.AccessLogType == AccessLogType)
|
||||||
.Where(x=>x.CreationTime>=DateTime.Now.AddMonths(-3))
|
.Where(x => x.CreationTime >= DateTime.Now.AddMonths(-3))
|
||||||
.OrderBy(x => x.CreationTime).ToListAsync();
|
.OrderBy(x => x.CreationTime).ToListAsync();
|
||||||
var output = entities.Adapt<List<AccessLogDto>>();
|
var output = entities.Adapt<List<AccessLogDto>>();
|
||||||
output?.ForEach(x => x.CreationTime = x.CreationTime.Date);
|
output?.ForEach(x => x.CreationTime = x.CreationTime.Date);
|
||||||
@@ -62,7 +66,7 @@ namespace Yi.Framework.Bbs.Application.Services
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 触发
|
/// 首页点击触发
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
[HttpPost("access-log")]
|
[HttpPost("access-log")]
|
||||||
@@ -77,17 +81,20 @@ namespace Yi.Framework.Bbs.Application.Services
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
await _repository._Db.Updateable<AccessLogAggregateRoot>().SetColumns(it => it.Number == it.Number + 1).Where(it => it.Id == last.Id).ExecuteCommandAsync();
|
await _repository._Db.Updateable<AccessLogAggregateRoot>().SetColumns(it => it.Number == it.Number + 1)
|
||||||
|
.Where(it => it.Id == last.Id).ExecuteCommandAsync();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 获取当前周数据
|
/// 获取当前周首页点击数据
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public async Task<AccessLogDto[]> GetWeekAsync()
|
public async Task<AccessLogDto[]> GetWeekAsync()
|
||||||
{
|
{
|
||||||
var lastSeven = await _repository._DbQueryable.OrderByDescending(x => x.CreationTime).ToPageListAsync(1, 7);
|
var lastSeven = await _repository._DbQueryable
|
||||||
|
.Where(x => x.AccessLogType == AccessLogTypeEnum.HomeClick)
|
||||||
|
.OrderByDescending(x => x.CreationTime).ToPageListAsync(1, 7);
|
||||||
|
|
||||||
return WeekTimeHandler(lastSeven.ToArray());
|
return WeekTimeHandler(lastSeven.ToArray());
|
||||||
}
|
}
|
||||||
@@ -99,7 +106,8 @@ namespace Yi.Framework.Bbs.Application.Services
|
|||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private AccessLogDto[] WeekTimeHandler(AccessLogAggregateRoot[] data)
|
private AccessLogDto[] WeekTimeHandler(AccessLogAggregateRoot[] data)
|
||||||
{
|
{
|
||||||
data = data.Where(x => x.CreationTime >= GetWeekFirst()).OrderByDescending(x => x.CreationTime).DistinctBy(x => x.CreationTime.DayOfWeek).ToArray();
|
data = data.Where(x => x.CreationTime >= GetWeekFirst()).OrderByDescending(x => x.CreationTime)
|
||||||
|
.DistinctBy(x => x.CreationTime.DayOfWeek).ToArray();
|
||||||
|
|
||||||
Dictionary<DayOfWeek, AccessLogDto> processedData = new Dictionary<DayOfWeek, AccessLogDto>();
|
Dictionary<DayOfWeek, AccessLogDto> processedData = new Dictionary<DayOfWeek, AccessLogDto>();
|
||||||
|
|
||||||
@@ -117,8 +125,8 @@ namespace Yi.Framework.Bbs.Application.Services
|
|||||||
// 如果当天有数据,则更新字典中的值为对应的Number
|
// 如果当天有数据,则更新字典中的值为对应的Number
|
||||||
var sss = data.Adapt<AccessLogDto>();
|
var sss = data.Adapt<AccessLogDto>();
|
||||||
processedData[dayOfWeek] = item.Adapt<AccessLogDto>();
|
processedData[dayOfWeek] = item.Adapt<AccessLogDto>();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var result = processedData.Values.ToList();
|
var result = processedData.Values.ToList();
|
||||||
|
|
||||||
//此时的时间是周日-周一-周二,需要处理
|
//此时的时间是周日-周一-周二,需要处理
|
||||||
@@ -128,8 +136,5 @@ namespace Yi.Framework.Bbs.Application.Services
|
|||||||
|
|
||||||
return result.ToArray();
|
return result.ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
namespace Yi.Framework.Bbs.Domain.Shared.Caches;
|
||||||
|
|
||||||
|
public class AccessLogCacheItem
|
||||||
|
{
|
||||||
|
public AccessLogCacheItem(long number)
|
||||||
|
{
|
||||||
|
Number = number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long Number { get; set; }
|
||||||
|
public DateTime LastModificationTime { get; set; }=DateTime.Now;
|
||||||
|
|
||||||
|
public DateTime LastInsertTime { get; set; }=DateTime.Now;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class AccessLogCacheConst
|
||||||
|
{
|
||||||
|
|
||||||
|
public const string Key = "AccessLog";
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
namespace Yi.Framework.Bbs.Domain.Shared.Enums;
|
||||||
|
|
||||||
|
public enum AccessLogTypeEnum
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 首页点击量
|
||||||
|
/// </summary>
|
||||||
|
HomeClick,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 接口请求量
|
||||||
|
/// </summary>
|
||||||
|
Request
|
||||||
|
}
|
||||||
@@ -1,16 +1,19 @@
|
|||||||
using SqlSugar;
|
using SqlSugar;
|
||||||
using Volo.Abp.Auditing;
|
using Volo.Abp.Auditing;
|
||||||
using Volo.Abp.Domain.Entities;
|
using Volo.Abp.Domain.Entities;
|
||||||
|
using Yi.Framework.Bbs.Domain.Shared.Enums;
|
||||||
|
|
||||||
namespace Yi.Framework.Bbs.Domain.Entities
|
namespace Yi.Framework.Bbs.Domain.Entities
|
||||||
{
|
{
|
||||||
[SugarTable("AccessLog")]
|
[SugarTable("AccessLog")]
|
||||||
public class AccessLogAggregateRoot : AggregateRoot<Guid>, IHasModificationTime, IHasCreationTime
|
public class AccessLogAggregateRoot : AggregateRoot<Guid>, IHasCreationTime,IHasModificationTime
|
||||||
{
|
{
|
||||||
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true)]
|
[SugarColumn(ColumnName = "Id", IsPrimaryKey = true)]
|
||||||
public override Guid Id { get; protected set; }
|
public override Guid Id { get; protected set; }
|
||||||
public long Number { get; set; }
|
public long Number { get; set; }
|
||||||
public DateTime? LastModificationTime { get; set; }
|
|
||||||
|
public AccessLogTypeEnum AccessLogType { get; set; }
|
||||||
public DateTime CreationTime { get; set; }
|
public DateTime CreationTime { get; set; }
|
||||||
|
public DateTime? LastModificationTime { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ using Yi.Framework.AspNetCore.Authentication.OAuth.QQ;
|
|||||||
using Yi.Framework.AspNetCore.Microsoft.AspNetCore.Builder;
|
using Yi.Framework.AspNetCore.Microsoft.AspNetCore.Builder;
|
||||||
using Yi.Framework.AspNetCore.Microsoft.Extensions.DependencyInjection;
|
using Yi.Framework.AspNetCore.Microsoft.Extensions.DependencyInjection;
|
||||||
using Yi.Framework.Bbs.Application;
|
using Yi.Framework.Bbs.Application;
|
||||||
|
using Yi.Framework.Bbs.Application.Extensions;
|
||||||
using Yi.Framework.ChatHub.Application;
|
using Yi.Framework.ChatHub.Application;
|
||||||
using Yi.Framework.CodeGen.Application;
|
using Yi.Framework.CodeGen.Application;
|
||||||
using Yi.Framework.Rbac.Application;
|
using Yi.Framework.Rbac.Application;
|
||||||
@@ -39,8 +40,6 @@ namespace Yi.Abp.Web
|
|||||||
[DependsOn(
|
[DependsOn(
|
||||||
typeof(YiAbpSqlSugarCoreModule),
|
typeof(YiAbpSqlSugarCoreModule),
|
||||||
typeof(YiAbpApplicationModule),
|
typeof(YiAbpApplicationModule),
|
||||||
|
|
||||||
|
|
||||||
typeof(AbpAspNetCoreMultiTenancyModule),
|
typeof(AbpAspNetCoreMultiTenancyModule),
|
||||||
typeof(AbpAspNetCoreMvcModule),
|
typeof(AbpAspNetCoreMvcModule),
|
||||||
typeof(AbpAutofacModule),
|
typeof(AbpAutofacModule),
|
||||||
@@ -50,11 +49,11 @@ namespace Yi.Abp.Web
|
|||||||
typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
|
typeof(AbpAspNetCoreAuthenticationJwtBearerModule),
|
||||||
typeof(YiFrameworkAspNetCoreModule),
|
typeof(YiFrameworkAspNetCoreModule),
|
||||||
typeof(YiFrameworkAspNetCoreAuthenticationOAuthModule)
|
typeof(YiFrameworkAspNetCoreAuthenticationOAuthModule)
|
||||||
|
)]
|
||||||
)]
|
|
||||||
public class YiAbpWebModule : AbpModule
|
public class YiAbpWebModule : AbpModule
|
||||||
{
|
{
|
||||||
private const string DefaultCorsPolicyName = "Default";
|
private const string DefaultCorsPolicyName = "Default";
|
||||||
|
|
||||||
public override Task ConfigureServicesAsync(ServiceConfigurationContext context)
|
public override Task ConfigureServicesAsync(ServiceConfigurationContext context)
|
||||||
{
|
{
|
||||||
var configuration = context.Services.GetConfiguration();
|
var configuration = context.Services.GetConfiguration();
|
||||||
@@ -70,20 +69,23 @@ namespace Yi.Abp.Web
|
|||||||
});
|
});
|
||||||
|
|
||||||
//配置错误处理显示详情
|
//配置错误处理显示详情
|
||||||
Configure<AbpExceptionHandlingOptions>(options =>
|
Configure<AbpExceptionHandlingOptions>(options => { options.SendExceptionsDetailsToClients = true; });
|
||||||
{
|
|
||||||
options.SendExceptionsDetailsToClients = true;
|
|
||||||
});
|
|
||||||
|
|
||||||
//动态Api
|
//动态Api
|
||||||
Configure<AbpAspNetCoreMvcOptions>(options =>
|
Configure<AbpAspNetCoreMvcOptions>(options =>
|
||||||
{
|
{
|
||||||
options.ConventionalControllers.Create(typeof(YiAbpApplicationModule).Assembly, options => options.RemoteServiceName = "default");
|
options.ConventionalControllers.Create(typeof(YiAbpApplicationModule).Assembly,
|
||||||
options.ConventionalControllers.Create(typeof(YiFrameworkRbacApplicationModule).Assembly, options => options.RemoteServiceName = "rbac");
|
options => options.RemoteServiceName = "default");
|
||||||
options.ConventionalControllers.Create(typeof(YiFrameworkBbsApplicationModule).Assembly, options => options.RemoteServiceName = "bbs");
|
options.ConventionalControllers.Create(typeof(YiFrameworkRbacApplicationModule).Assembly,
|
||||||
options.ConventionalControllers.Create(typeof(YiFrameworkChatHubApplicationModule).Assembly, options => options.RemoteServiceName = "chat-hub");
|
options => options.RemoteServiceName = "rbac");
|
||||||
options.ConventionalControllers.Create(typeof(YiFrameworkTenantManagementApplicationModule).Assembly, options => options.RemoteServiceName = "tenant-management");
|
options.ConventionalControllers.Create(typeof(YiFrameworkBbsApplicationModule).Assembly,
|
||||||
options.ConventionalControllers.Create(typeof(YiFrameworkCodeGenApplicationModule).Assembly, options => options.RemoteServiceName = "code-gen");
|
options => options.RemoteServiceName = "bbs");
|
||||||
|
options.ConventionalControllers.Create(typeof(YiFrameworkChatHubApplicationModule).Assembly,
|
||||||
|
options => options.RemoteServiceName = "chat-hub");
|
||||||
|
options.ConventionalControllers.Create(typeof(YiFrameworkTenantManagementApplicationModule).Assembly,
|
||||||
|
options => options.RemoteServiceName = "tenant-management");
|
||||||
|
options.ConventionalControllers.Create(typeof(YiFrameworkCodeGenApplicationModule).Assembly,
|
||||||
|
options => options.RemoteServiceName = "code-gen");
|
||||||
|
|
||||||
//统一前缀
|
//统一前缀
|
||||||
options.ConventionalControllers.ConventionalControllerSettings.ForEach(x => x.RootPath = "api/app");
|
options.ConventionalControllers.ConventionalControllerSettings.ForEach(x => x.RootPath = "api/app");
|
||||||
@@ -98,22 +100,20 @@ namespace Yi.Abp.Web
|
|||||||
|
|
||||||
//设置缓存不要过期,默认滑动20分钟
|
//设置缓存不要过期,默认滑动20分钟
|
||||||
Configure<AbpDistributedCacheOptions>(cacheOptions =>
|
Configure<AbpDistributedCacheOptions>(cacheOptions =>
|
||||||
{
|
|
||||||
cacheOptions.GlobalCacheEntryOptions.SlidingExpiration = null;
|
|
||||||
//缓存key前缀
|
|
||||||
cacheOptions.KeyPrefix = "Yi:";
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
Configure<AbpAntiForgeryOptions>(options =>
|
|
||||||
{
|
{
|
||||||
options.AutoValidate = false;
|
cacheOptions.GlobalCacheEntryOptions.SlidingExpiration = null;
|
||||||
|
//缓存key前缀
|
||||||
|
cacheOptions.KeyPrefix = "Yi:";
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
|
Configure<AbpAntiForgeryOptions>(options => { options.AutoValidate = false; });
|
||||||
|
|
||||||
//Swagger
|
//Swagger
|
||||||
context.Services.AddYiSwaggerGen<YiAbpWebModule>(options =>
|
context.Services.AddYiSwaggerGen<YiAbpWebModule>(options =>
|
||||||
{
|
{
|
||||||
options.SwaggerDoc("default", new OpenApiInfo { Title = "Yi.Framework.Abp", Version = "v1", Description = "集大成者" });
|
options.SwaggerDoc("default",
|
||||||
|
new OpenApiInfo { Title = "Yi.Framework.Abp", Version = "v1", Description = "集大成者" });
|
||||||
});
|
});
|
||||||
|
|
||||||
//跨域
|
//跨域
|
||||||
@@ -152,7 +152,7 @@ namespace Yi.Abp.Web
|
|||||||
//每60秒限制100个请求,滑块添加,分6段
|
//每60秒限制100个请求,滑块添加,分6段
|
||||||
service.AddRateLimiter(_ =>
|
service.AddRateLimiter(_ =>
|
||||||
{
|
{
|
||||||
_.RejectionStatusCode = StatusCodes.Status429TooManyRequests;
|
_.RejectionStatusCode = StatusCodes.Status429TooManyRequests;
|
||||||
_.OnRejected = (context, _) =>
|
_.OnRejected = (context, _) =>
|
||||||
{
|
{
|
||||||
if (context.Lease.TryGetMetadata(MetadataName.RetryAfter, out var retryAfter))
|
if (context.Lease.TryGetMetadata(MetadataName.RetryAfter, out var retryAfter))
|
||||||
@@ -160,6 +160,7 @@ namespace Yi.Abp.Web
|
|||||||
context.HttpContext.Response.Headers.RetryAfter =
|
context.HttpContext.Response.Headers.RetryAfter =
|
||||||
((int)retryAfter.TotalSeconds).ToString(NumberFormatInfo.InvariantInfo);
|
((int)retryAfter.TotalSeconds).ToString(NumberFormatInfo.InvariantInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
context.HttpContext.Response.StatusCode = StatusCodes.Status429TooManyRequests;
|
context.HttpContext.Response.StatusCode = StatusCodes.Status429TooManyRequests;
|
||||||
context.HttpContext.Response.WriteAsync("Too many requests. Please try again later.");
|
context.HttpContext.Response.WriteAsync("Too many requests. Please try again later.");
|
||||||
|
|
||||||
@@ -168,20 +169,20 @@ namespace Yi.Abp.Web
|
|||||||
|
|
||||||
//全局使用,链式表达式
|
//全局使用,链式表达式
|
||||||
_.GlobalLimiter = PartitionedRateLimiter.CreateChained(
|
_.GlobalLimiter = PartitionedRateLimiter.CreateChained(
|
||||||
PartitionedRateLimiter.Create<HttpContext, string>(httpContext =>
|
PartitionedRateLimiter.Create<HttpContext, string>(httpContext =>
|
||||||
{
|
{
|
||||||
var userAgent = httpContext.Request.Headers.UserAgent.ToString();
|
var userAgent = httpContext.Request.Headers.UserAgent.ToString();
|
||||||
|
|
||||||
return RateLimitPartition.GetSlidingWindowLimiter
|
return RateLimitPartition.GetSlidingWindowLimiter
|
||||||
(userAgent, _ =>
|
(userAgent, _ =>
|
||||||
new SlidingWindowRateLimiterOptions
|
new SlidingWindowRateLimiterOptions
|
||||||
{
|
{
|
||||||
PermitLimit = 1000,
|
PermitLimit = 1000,
|
||||||
Window = TimeSpan.FromSeconds(60),
|
Window = TimeSpan.FromSeconds(60),
|
||||||
SegmentsPerWindow = 6,
|
SegmentsPerWindow = 6,
|
||||||
QueueProcessingOrder = QueueProcessingOrder.OldestFirst
|
QueueProcessingOrder = QueueProcessingOrder.OldestFirst
|
||||||
});
|
});
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@@ -203,14 +204,15 @@ namespace Yi.Abp.Web
|
|||||||
options.Events = new JwtBearerEvents
|
options.Events = new JwtBearerEvents
|
||||||
{
|
{
|
||||||
OnMessageReceived = context =>
|
OnMessageReceived = context =>
|
||||||
{
|
|
||||||
var accessToken = context.Request.Query["access_token"];
|
|
||||||
if (!string.IsNullOrEmpty(accessToken))
|
|
||||||
{
|
{
|
||||||
context.Token = accessToken;
|
var accessToken = context.Request.Query["access_token"];
|
||||||
|
if (!string.IsNullOrEmpty(accessToken))
|
||||||
|
{
|
||||||
|
context.Token = accessToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
})
|
})
|
||||||
.AddJwtBearer(TokenTypeConst.Refresh, options =>
|
.AddJwtBearer(TokenTypeConst.Refresh, options =>
|
||||||
@@ -221,37 +223,32 @@ namespace Yi.Abp.Web
|
|||||||
ValidateIssuerSigningKey = true,
|
ValidateIssuerSigningKey = true,
|
||||||
ValidIssuer = refreshJwtOptions.Issuer,
|
ValidIssuer = refreshJwtOptions.Issuer,
|
||||||
ValidAudience = refreshJwtOptions.Audience,
|
ValidAudience = refreshJwtOptions.Audience,
|
||||||
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(refreshJwtOptions.SecurityKey))
|
IssuerSigningKey =
|
||||||
|
new SymmetricSecurityKey(Encoding.UTF8.GetBytes(refreshJwtOptions.SecurityKey))
|
||||||
};
|
};
|
||||||
options.Events = new JwtBearerEvents
|
options.Events = new JwtBearerEvents
|
||||||
{
|
{
|
||||||
OnMessageReceived = context =>
|
OnMessageReceived = context =>
|
||||||
{
|
|
||||||
var refresh_token = context.Request.Headers["refresh_token"];
|
|
||||||
if (!string.IsNullOrEmpty(refresh_token))
|
|
||||||
{
|
{
|
||||||
context.Token = refresh_token;
|
var refresh_token = context.Request.Headers["refresh_token"];
|
||||||
|
if (!string.IsNullOrEmpty(refresh_token))
|
||||||
|
{
|
||||||
|
context.Token = refresh_token;
|
||||||
|
return Task.CompletedTask;
|
||||||
|
}
|
||||||
|
|
||||||
|
var refreshToken = context.Request.Query["refresh_token"];
|
||||||
|
if (!string.IsNullOrEmpty(refreshToken))
|
||||||
|
{
|
||||||
|
context.Token = refreshToken;
|
||||||
|
}
|
||||||
|
|
||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
var refreshToken = context.Request.Query["refresh_token"];
|
|
||||||
if (!string.IsNullOrEmpty(refreshToken))
|
|
||||||
{
|
|
||||||
context.Token = refreshToken;
|
|
||||||
}
|
|
||||||
|
|
||||||
return Task.CompletedTask;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
})
|
})
|
||||||
.AddQQ(options =>
|
.AddQQ(options => { configuration.GetSection("OAuth:QQ").Bind(options); })
|
||||||
{
|
.AddGitee(options => { configuration.GetSection("OAuth:Gitee").Bind(options); });
|
||||||
configuration.GetSection("OAuth:QQ").Bind(options);
|
|
||||||
})
|
|
||||||
.AddGitee(options =>
|
|
||||||
{
|
|
||||||
configuration.GetSection("OAuth:Gitee").Bind(options);
|
|
||||||
});
|
|
||||||
|
|
||||||
//授权
|
//授权
|
||||||
context.Services.AddAuthorization();
|
context.Services.AddAuthorization();
|
||||||
@@ -291,6 +288,9 @@ namespace Yi.Abp.Web
|
|||||||
//swagger
|
//swagger
|
||||||
app.UseYiSwagger();
|
app.UseYiSwagger();
|
||||||
|
|
||||||
|
//流量访问统计,不启用
|
||||||
|
//app.UseAccessLog();
|
||||||
|
|
||||||
//请求处理
|
//请求处理
|
||||||
app.UseYiApiHandlinge();
|
app.UseYiApiHandlinge();
|
||||||
|
|
||||||
@@ -317,4 +317,4 @@ namespace Yi.Abp.Web
|
|||||||
return Task.CompletedTask;
|
return Task.CompletedTask;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user