diff --git "a/\346\234\261\345\276\267\346\230\216/2021-07-06.md" "b/\346\234\261\345\276\267\346\230\216/2021-07-06.md" index d185d1a71180a307dc50ee6be4acae6d9d18bb3e..40383e424b75627d23bf940a717d08037c768dd7 100644 --- "a/\346\234\261\345\276\267\346\230\216/2021-07-06.md" +++ "b/\346\234\261\345\276\267\346\230\216/2021-07-06.md" @@ -66,3 +66,74 @@ Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hc ### 后面可以访问到信息啦 ![图片](./imgs/2021-07-06.1.jpg) + + +# 刷新Token +### 在Params创建文件RefreshToken.cs +``` +namespace ApiTest.Api.Params +{ + public class RefreshTokenDTO + { + public string Token { get; set; } + public string refreshToken { get; set; } + } +} +``` + +### UsersController.cs加入新代码 +``` +[AllowAnonymous] + [HttpPost, Route("refreshtoken")] + public dynamic RefreshToken(RefreshTokenDTO refresh) + { + var username = TokenHelper.ValidateToken(_tokenParameter, refresh); + + if (string.IsNullOrEmpty(username)) + { + return new { Code = 1002, Data = "", Msg = "token验证失败" }; + } + + var token = TokenHelper.GenerateToekn(_tokenParameter,username); + var refreshToken = "112358"; + + return new { + Code = 1000, + Data = new { Token = token, refreshToken = refreshToken }, + Msg = "刷新token成功^_^" + }; + } + +``` + +### .http文件加入新代码 +``` +### 刷新重新获取token +POST http://localhost:5000/users/refreshtoken HTTP/1.1 +Content-Type: application/json + +{ + "token":"eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJodHRwOi8vc2NoZW1hcy54bWxzb2FwLm9yZy93cy8yMDA1LzA1L2lkZW50aXR5L2NsYWltcy9uYW1lIjoiYWRtaW4iLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJhZG1pbiIsImV4cCI6MTYyNTczODExMywiaXNzIjoiemh1emh1In0.p93sueqGudKolh8CpPaXhMEGWpXzIsgp474JMsvXupU", + "refreshtoken":"113" +} +``` + +效果如下: +![图片](./imgs/2021-07-06.3.jpg) + +### 加入代码,消除过期时间设置成少于五分钟的时长,token生效问题 +``` +在生成Token时,我们把过期时间设置成少于五分钟的时长,比方3分钟。但这时,实测会发现,Token的过期失效了。 + +为什么呢? + +TokenValidationParameters有一个属性叫ClockSkew,这个参数有个默认值是TimeSpan.FromMinutes(5)。 + +这个参数的意义是:考虑到各个服务器之间的时间不一定完全同步,系统给了个5分钟的误差时间。 + +这个误差时间导致的结果是:少于五分钟的过期时间,会在实际认证检查时被忽略。 +``` +![图片](./imgs/2021-07-06.4.jpg) + + +### 当我们将刷新时间设置为两分钟时,过了两分钟他就会重新生成一个新的token,那么旧的token就不能用了!!! \ No newline at end of file diff --git "a/\346\234\261\345\276\267\346\230\216/2021-07-08.md" "b/\346\234\261\345\276\267\346\230\216/2021-07-08.md" new file mode 100644 index 0000000000000000000000000000000000000000..012907aa95b5b09ed728a4107a63428cec7ff5ab --- /dev/null +++ "b/\346\234\261\345\276\267\346\230\216/2021-07-08.md" @@ -0,0 +1,301 @@ +# .Net Core 审计日志 +``` +审计日志:   +维基百科: “审计跟踪(也叫审计日志)是与安全相关的按照时间顺序的记录,记录集或者记录源,它们提供了活动序列的文档证据,这些活动序列可以在任何时间影响一个特定的操作,步骤或其他” +``` +### 作用 +``` + 1、快速定位问题耗时及性能情况 + +  2、记录调用时环境信息:如浏览器、参数等 +``` +### 如何实现思路 +``` +获取调用接口方法时相关信息 + +记录当前接口耗时情况 + +保存审计日志信息到数据库中 + +  那么如何获取调用接口时相关信息呢?.Net Core中可以使用:过滤器、拦截器 实现。  +``` + +### 在Entity下创建AuditInfo +``` +using System; +using System.Collections.Generic; + + +namespace ApiTest.Api.Entity +{ + /// + /// 角色实体 + /// + public class AuditInfo : BaseInit + { + /// + /// 调用参数 + /// + public string Parameters { get; set; } + + /// + /// 浏览器信息 + /// + public string BrowserInfo { get; set; } + + /// + /// 客户端信息 + /// + public string ClientName { get; set; } + + /// + /// 客户端IP地址 + /// + public string ClientIpAddress { get; set; } + + /// + /// 执行耗时 + /// + public int ExecutionDuration { get; set; } + + /// + /// 执行时间 + /// + public DateTime ExecutionTime { get; set; } + + /// + /// 返回内容 + /// + public string ReturnValue { get; set; } + + /// + /// 异常对象 + /// + public string Exception { get; set; } + + /// + /// 方法名 + /// + public string MethodName { get; set; } + + /// + /// 服务名 + /// + public string ServiceName { get; set; } + + /// + /// 调用者信息 + /// + public string UserInfo { get; set; } + + /// + /// 自定义数据 + /// + public string CustomData { get; set; } + } +} +``` + +### 创建Filters下创建AuditLogActionFilter.cs +``` +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Reflection; +using System.Threading.Tasks; +using ApiTest.Api.Entity; +using ApiTest.Api.Repository; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Controllers; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.Extensions.Logging; +using Newtonsoft.Json; + +namespace ApiTest.Api.Filters +{ + public class AuditLogActionFilter : IAsyncActionFilter + { + /// + /// 登录用户 + /// + // private readonly ISession _Session; + /// + /// 日志记录 + /// + private readonly ILogger _logger; + + private readonly IRepository _auditLogService; + + public AuditLogActionFilter(// ISession Session, + + ILogger logger, + IRepository auditLogService + ) + { + // _Session = Session; + _logger = logger; + _auditLogService = auditLogService; + } + + public async Task + OnActionExecutionAsync( + ActionExecutingContext context, + ActionExecutionDelegate next + ) + { + // 判断是否写日志 + if (!ShouldSaveAudit(context)) + { + await next(); + return; + } + + //接口Type + var type = + (context.ActionDescriptor as ControllerActionDescriptor) + .ControllerTypeInfo + .AsType(); + + //方法信息 + var method = + (context.ActionDescriptor as ControllerActionDescriptor) + .MethodInfo; + + //方法参数 + var arguments = context.ActionArguments; + + //开始计时 + var stopwatch = Stopwatch.StartNew(); + var auditInfo = + new AuditInfo { + // UserInfo = _Session?.Id, + UserInfo = 1.ToString(), + ServiceName = type != null ? type.FullName : "", + MethodName = method.Name, + ////请求参数转Json + Parameters = JsonConvert.SerializeObject(arguments), + ExecutionTime = DateTime.Now, + BrowserInfo = + context + .HttpContext + .Request + .Headers["User-Agent"] + .ToString(), + ClientIpAddress = + context + .HttpContext + .Connection + .RemoteIpAddress + .ToString() + //ClientName = _clientInfoProvider.ComputerName.TruncateWithPostfix(EntityDefault.FieldsLength100), + // Id = Guid.NewGuid().ToString() + }; + + ActionExecutedContext result = null; + try + { + result = await next(); + if (result.Exception != null && !result.ExceptionHandled) + { + auditInfo.Exception = result.Exception.ToString(); + } + } + catch (Exception ex) + { + auditInfo.Exception = ex.ToString(); + throw; + } + finally + { + stopwatch.Stop(); + auditInfo.ExecutionDuration = + Convert.ToInt32(stopwatch.Elapsed.TotalMilliseconds); + + if (result != null) + { + switch (result.Result) + { + case ObjectResult objectResult: + auditInfo.ReturnValue = + JsonConvert.SerializeObject(objectResult.Value); + break; + case JsonResult jsonResult: + auditInfo.ReturnValue = + JsonConvert.SerializeObject(jsonResult.Value); + break; + case ContentResult contentResult: + auditInfo.ReturnValue = contentResult.Content; + break; + } + } + Console.WriteLine(auditInfo.ToString()); + + //保存审计日志 + await _auditLogService.InsertAsync(auditInfo); + } + } + + /// + /// 是否需要记录审计 + /// + /// + /// + private bool ShouldSaveAudit(ActionExecutingContext context) + { + if (!(context.ActionDescriptor is ControllerActionDescriptor)) + return false; + var methodInfo = + (context.ActionDescriptor as ControllerActionDescriptor) + .MethodInfo; + + if (methodInfo == null) + { + return false; + } + + if (!methodInfo.IsPublic) + { + return false; + } + + // if (methodInfo.GetCustomAttribute() != null) + // { + // return true; + // } + // if (methodInfo.GetCustomAttribute() != null) + // { + // return false; + // } + // var classType = methodInfo.DeclaringType; + // if (classType != null) + // { + // if (classType.GetTypeInfo().GetCustomAttribute() != null) + // { + // return true; + // } + // if (classType.GetTypeInfo().GetCustomAttribute() != null) + // { + // return false; + // } + // } + return true; + } + } +} +``` + +### Startup.cs 加入代码 +``` +引入using ApiTest.Api.Filters; + +services.AddControllers(options=> + { + options.Filters.Add(typeof(AuditLogActionFilter)); + }); +``` + +### 随后运行,接下来你的任何操作,会被数据库记录,并且打印出来 +如下: +![图片](./imgs/2021-07-08.1.jpg) \ No newline at end of file diff --git "a/\346\234\261\345\276\267\346\230\216/imgs/2021-07-06.3.jpg" "b/\346\234\261\345\276\267\346\230\216/imgs/2021-07-06.3.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..1a4f33cd5d3e96719bad92b6795fdb098a34a8df Binary files /dev/null and "b/\346\234\261\345\276\267\346\230\216/imgs/2021-07-06.3.jpg" differ diff --git "a/\346\234\261\345\276\267\346\230\216/imgs/2021-07-06.4.jpg" "b/\346\234\261\345\276\267\346\230\216/imgs/2021-07-06.4.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..6e35ac6e487a603788a438ce612b4864f8bf0fab Binary files /dev/null and "b/\346\234\261\345\276\267\346\230\216/imgs/2021-07-06.4.jpg" differ diff --git "a/\346\234\261\345\276\267\346\230\216/imgs/2021-07-08.1.jpg" "b/\346\234\261\345\276\267\346\230\216/imgs/2021-07-08.1.jpg" new file mode 100644 index 0000000000000000000000000000000000000000..46911cccbda7c613c164d9776350e7e8a18b60f5 Binary files /dev/null and "b/\346\234\261\345\276\267\346\230\216/imgs/2021-07-08.1.jpg" differ