Commit 6c529f59 by zry

filter

parent 40e5f020
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Options;
using Newtonsoft.Json.Linq;
using Performance.DtoModels;
using Performance.DtoModels.AppSettings;
using Performance.Infrastructure;
using Performance.Services;
using System;
......@@ -14,15 +17,34 @@ namespace Performance.Api.Controllers
public class AccountController : Controller
{
UserService _userService;
public AccountController(UserService userService)
IMemoryCache _memoryCache;
Application _options;
public AccountController(UserService userService,
IMemoryCache memoryCache,
IOptions<Application> options)
{
_userService = userService;
_memoryCache = memoryCache;
_options = options.Value;
}
[NoVerify]
[HttpPost]
public ApiResponse<LoginResponse> Login([FromBody]LoginRequest request)
public ApiResponse<LoginInfo> Login([FromBody]LoginRequest request)
{
return _userService.Login(request);
var response = _userService.Login(request);
if (response.State == ResponseType.OK)
{
if (string.IsNullOrEmpty(response.Data.Token))
response.Data.Token = Guid.NewGuid().ToString("N");
var option = new MemoryCacheEntryOptions()
{
SlidingExpiration = TimeSpan.FromMinutes(_options.ExpirationMinutes)
};
_memoryCache.Set(response.Data.Token, response.Data, option);
}
return response;
}
}
}
......@@ -19,7 +19,8 @@ public ActionResult<IEnumerable<string>> Get()
// GET api/values/5
[HttpGet("{id}")]
public ActionResult<string> Get(int id)
[NoVerify]
public ActionResult<string> Getid(int id)
{
return "value";
}
......
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Internal;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.Extensions.Logging;
using Performance.DtoModels;
using Performance.Infrastructure;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Performance.Api
{
public class ActionsFilter : IAsyncActionFilter
{
private readonly ILoggerFactory factory;
private readonly ILogger<ActionsFilter> logger;
private readonly IMemoryCache cache;
public ActionsFilter(ILoggerFactory factory)
public ActionsFilter(ILoggerFactory factory, IMemoryCache cache)
{
this.factory = factory;
this.logger = factory.CreateLogger<ActionsFilter>();
this.cache = cache;
}
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
var logger = factory.CreateLogger<ActionsFilter>();
logger.LogWarning($"action filter is executing new ,context.modelstate:{context.ModelState.IsValid}");
logger.BeginScope("s+++++++++++++++++++++++++++++++++");
var request = context.HttpContext.Request;
//启用body倒带功能
request.EnableRewind();
//记录Request请求
var kv = GetRequestContent(request);
logger.LogInformation($"请求内容 {request.Method}:{JsonHelper.Serialize(kv)}");
//token验证
var arry = ((ControllerActionDescriptor)context.ActionDescriptor).MethodInfo.GetCustomAttributes(typeof(NoVerifyAttribute), true);
if (arry.Length == 0)
{
var token = kv.GetValue("token", "");
var user = cache.Get<LoginInfo>(token);
if (string.IsNullOrEmpty(token) || user == null || user.Token.Equals(token))
{
var response = new ApiResponse(ResponseType.TokenError, "Token无效");
context.Result = new ObjectResult(response);
return;
}
}
//验证请求参数
if (!context.ModelState.IsValid)
{
string errorMessage = string.Join(",", context.ModelState.Values.Select(t => t?.Errors?.FirstOrDefault()?.ErrorMessage));
var messageList = context.ModelState.Values
.Where(t => !string.IsNullOrEmpty(t?.Errors?.FirstOrDefault()?.ErrorMessage))
.Select(t => t?.Errors?.FirstOrDefault()?.ErrorMessage);
string errorMessage = string.Join(",", messageList);
var response = new ApiResponse(ResponseType.ParameterError, "参数错误", errorMessage);
context.Result = new ObjectResult(response);
return;
var jsonData = JsonHelper.Serialize(context.Result);
logger.LogInformation($"响应结果:{jsonData}");
}
//记录response结果
else
{
var executedContext = await next();
logger.LogWarning($"action filter is executed now,executedContext controller:{executedContext.Controller.ToString()}");
var objectResult = (ObjectResult)executedContext.Result;
var jsonData = JsonHelper.Serialize(objectResult.Value);
logger.LogInformation($"响应结果:{jsonData}");
}
}
/// <summary>
/// 读取请求内容
/// </summary>
/// <param name="request"></param>
/// <returns></returns>
private SortedDictionary<string, object> GetRequestContent(HttpRequest request)
{
if (request.Method.Equals("POST"))
{
if (request.Body.CanSeek)
{
var types = request.ContentType.Split(';');
if (types.Contains("application/json"))
{
using (var stream = request.Body)
{
stream.Position = 0;
var reader = new StreamReader(stream, Encoding.UTF8);
var requestContext = reader.ReadToEnd();
return JsonHelper.DeserializeLower(requestContext);
}
}
else if (types.Contains("application/x-www-form-urlencoded") || types.Contains("multipart/form-data"))
{
var requestContext = JsonHelper.Serialize(request.Form);
return JsonHelper.DeserializeLower(requestContext);
}
else if (types.Contains("text/xml"))
{
//暂不处理
}
}
}
else
{
if (request.Query.Count > 0)
{
var kv = new SortedDictionary<string, object>();
foreach (var item in request.Query)
{
kv.Add(item.Key, item.Value);
}
return kv;
}
}
return new SortedDictionary<string, object>();
}
}
[AttributeUsage(AttributeTargets.Method)]
public class NoVerifyAttribute : Attribute { }
}
......@@ -20,7 +20,7 @@ public ExceptionsFilter(ILoggerFactory loggerFactory)
public Task OnExceptionAsync(ExceptionContext context)
{
var logger = loggerFactory.CreateLogger<ExceptionsFilter>();
logger.LogError($"接口异常:{context.Exception.Message}");
logger.LogError($"接口异常:{context.Exception.ToString()}");
var response = new ApiResponse(ResponseType.Error, "接口异常", context.Exception.Message);
context.Result = new ObjectResult(response);
return Task.CompletedTask;
......
......@@ -12,6 +12,7 @@
<PackageReference Include="Microsoft.AspNetCore.App" />
<PackageReference Include="Microsoft.AspNetCore.Razor.Design" Version="2.2.0" PrivateAssets="All" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.2.0" />
<PackageReference Include="Microsoft.Extensions.Caching.Memory" Version="2.2.0" />
<PackageReference Include="MySql.Data" Version="8.0.15" />
<PackageReference Include="MySql.Data.EntityFrameworkCore" Version="8.0.15" />
<PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
......
{
"$schema": "http://json.schemastore.org/launchsettings.json",
{
"iisSettings": {
"windowsAuthentication": false,
"anonymousAuthentication": true,
......@@ -8,6 +7,7 @@
"sslPort": 0
}
},
"$schema": "http://json.schemastore.org/launchsettings.json",
"profiles": {
"IIS Express": {
"commandName": "IISExpress",
......@@ -21,10 +21,10 @@
"commandName": "Project",
"launchBrowser": true,
"launchUrl": "api/values",
"applicationUrl": "http://localhost:5001",
"environmentVariables": {
"ASPNETCORE_ENVIRONMENT": "Development"
}
},
"applicationUrl": "http://localhost:5001"
}
}
}
\ No newline at end of file
......@@ -76,15 +76,14 @@ public void ConfigureServices(IServiceCollection services)
}
});
services.AddAutoMapper(mapper =>
{
Mapper.Initialize(cfg => cfg.AddProfile<AutoMapperConfigs>());
});
services.AddAutoMapper();
services
.AddPerformanceService()
.AddPerformanceRepoitory()
.Configure<AppConnection>(Configuration.GetSection("AppConnection"));
.Configure<AppConnection>(Configuration.GetSection("AppConnection"))
.Configure<Application>(Configuration.GetSection("Application"));
var connection = services.BuildServiceProvider().GetService<IOptions<AppConnection>>();
......@@ -95,10 +94,17 @@ public void ConfigureServices(IServiceCollection services)
}
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory, ILoggingBuilder builder)
{
loggerFactory.AddNLog();
env.ConfigureNLog("nlog.config");
builder.AddConsole(configure =>
{
configure.IncludeScopes = true;
});
builder.AddNLog(new NLogProviderOptions
{
IncludeScopes = true
});
if (env.IsDevelopment())
{
app.UseDeveloperExceptionPage();
......
......@@ -4,8 +4,11 @@
"Default": "Warning"
}
},
"AllowedHosts": "*",
"AppConnection": {
"PerformanceConnectionString": "server=192.168.18.166;database=db_performance;uid=root;pwd=1234qwer;pooling=true;charset=utf8;convert zero datetime=true;port=3306;connection timeout=120;max pool size=512;allow user variables=true;"
},
"Application": {
//¼ʱ
"ExpirationMinutes": "1"
}
}
......@@ -8,5 +8,6 @@ namespace Performance.DtoModels
{
public class ApiRequest
{
public string Token { get; set; }
}
}
......@@ -33,7 +33,7 @@ public ApiResponse(ResponseType type, string message)
public ApiResponse(ResponseType type, string message, TEntity entity)
{
State = ResponseType.Fail;
State = type;
Message = message;
Data = entity;
}
......
using System;
using System.Collections.Generic;
using System.Text;
namespace Performance.DtoModels.AppSettings
{
public class Application
{
public int ExpirationMinutes { get; set; }
}
}
......@@ -10,9 +10,9 @@ public class AutoMapperConfigs : Profile
{
public AutoMapperConfigs()
{
CreateMap<LoginResponse, Sys_User>()
CreateMap<LoginInfo, Sys_User>()
.ForMember(dest => dest.ID, opt => opt.MapFrom(src => src.UserID));
CreateMap<Sys_User, LoginResponse>()
CreateMap<Sys_User, LoginInfo>()
.ForMember(dest => dest.UserID, opt => opt.MapFrom(src => src.ID));
}
}
......
......@@ -4,9 +4,12 @@
namespace Performance.DtoModels
{
public class LoginResponse
public class LoginInfo
{
public string Token { get; set; }
public int UserID { get; set; }
public DateTime CreatDate { get; set; }
public int CreateUser { get; set; }
public string RealName { get; set; }
public string Login { get; set; }
public string Mail { get; set; }
......
using System;
using System.Collections.Generic;
using System.Text;
namespace Performance.Infrastructure
{
/// <summary>
/// 类型转换
/// </summary>
public static class ConvertHelper
{
public static int TryInt(string inValue, int defaultValue = default(int))
{
int ret = defaultValue;
int.TryParse(inValue, out ret);
return ret;
}
public static long TryLong(string inValue, long defaultValue = default(int))
{
long ret = defaultValue;
long.TryParse(inValue, out ret);
return ret;
}
public static decimal TryDecimal(string inValue, decimal defaultValue = default(decimal))
{
decimal ret = defaultValue;
decimal.TryParse(inValue, out ret);
return ret;
}
public static DateTime TryDateTime(string inValue, DateTime defaultValue = default(DateTime))
{
DateTime ret = defaultValue;
DateTime.TryParse(inValue, out ret);
return ret;
}
/// <summary>
/// 返回默认值
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="param"></param>
/// <param name="defaultValue"></param>
/// <returns></returns>
public static T To<T>(object value, T defaultValue = default(T))
{
try
{
var t = typeof(T);
//兼容可空类型转换
if (t.IsGenericType && t.GetGenericTypeDefinition().Equals(typeof(Nullable<>)))
{
if (value == null)
{
return default(T);
}
t = Nullable.GetUnderlyingType(t);
}
return (T)Convert.ChangeType(value, t);
}
catch
{
return defaultValue;
}
}
/// <summary>
///
/// </summary>
/// <typeparam name = "T"></typeparam>
/// <param name = "value">The value.</param>
/// <param name = "defaultValue">The default value.</param>
/// <param name = "ignoreException">if set to <c>true</c> ignore any exception.</param>
/// <returns>The target type</returns>
public static T To<T>(object value, T defaultValue, bool ignoreException)
{
if (ignoreException)
{
try
{
return To<T>(value);
}
catch
{
return defaultValue;
}
}
return To<T>(value);
}
}
}
\ No newline at end of file
using System;
using System.Collections.Generic;
using System.Text;
namespace Performance.Infrastructure
{
public static partial class UtilExtensions
{
/// <summary>
/// 获取键值对指定key值,并进行类型转换
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="keyValues"></param>
/// <param name="key"></param>
/// <returns></returns>
public static T GetValue<T>(this Dictionary<string, object> keyValues, string key, T defaultValue = default(T))
{
object value;
if (keyValues.TryGetValue(key, out value))
return ConvertHelper.To<T>(value, defaultValue);
return defaultValue;
}
/// <summary>
/// 获取键值对指定key值,并进行类型转换
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="keyValues"></param>
/// <param name="key"></param>
/// <returns></returns>
public static T GetValue<T>(this SortedDictionary<string, object> keyValues, string key, T defaultValue = default(T))
{
object value;
if (keyValues.TryGetValue(key, out value))
return ConvertHelper.To<T>(value, defaultValue);
return defaultValue;
}
}
}
......@@ -24,23 +24,26 @@ public List<Sys_User> GetUser()
return _userRepository.GetEntities().ToList();
}
public ApiResponse<LoginResponse> Login(LoginRequest request)
public ApiResponse<LoginInfo> Login(LoginRequest request)
{
//手机号登录
if (request.LoginType == 1)
{
var user = _userRepository.GetEntity(t => t.Mobile == request.Account);
}
//账号密码登录
else if (request.LoginType == 2)
{
var user = _userRepository.GetEntity(t => t.Login == request.Account);
if (user != null && user.Password == request.Password)
{
var data = Mapper.Map<LoginResponse>(user);
return new ApiResponse<LoginResponse>(ResponseType.OK, "登录成功", data);
var data = Mapper.Map<LoginInfo>(user);
data.Token = Guid.NewGuid().ToString("N");
return new ApiResponse<LoginInfo>(ResponseType.OK, "登录成功", data);
}
}
return new ApiResponse<LoginResponse>();
return new ApiResponse<LoginInfo>();
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment