优化登录

This commit is contained in:
不做码农 2023-08-28 22:16:57 +08:00
parent ea3fa0e0d6
commit 52240ab6a8
12 changed files with 81 additions and 58 deletions

View File

@ -5,8 +5,6 @@ using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using System;
using System.Security.Claims;
using System.Security.Principal;
using System.Xml.Linq;
namespace Infrastructure
{

View File

@ -15,6 +15,7 @@
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="7.0.0" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
<PackageReference Include="UAParser" Version="3.1.47" />
<PackageReference Include="IPTools.China" Version="1.6.0" />
</ItemGroup>
</Project>

View File

@ -1,4 +1,5 @@
using Infrastructure.Extensions;
using IPTools.Core;
using Microsoft.AspNetCore.Http;
using System;
using System.Collections.Generic;
@ -197,14 +198,24 @@ namespace Infrastructure.WebExtensins
return c;
}
/// <summary>
/// 根据IP获取地理位置
/// </summary>
/// <returns></returns>
public static string GetIpInfo(string IP)
{
var ipInfo = IpTool.Search(IP);
return ipInfo?.Province + "-" + ipInfo?.City + "-" + ipInfo?.NetworkOperator;
}
/// <summary>
/// 设置请求参数
/// </summary>
/// <param name="reqMethod"></param>
/// <param name="context"></param>
public static string GetRequestValue(this HttpContext context,string reqMethod)
public static string GetRequestValue(this HttpContext context, string reqMethod)
{
string param= string.Empty;
string param = string.Empty;
if (HttpMethods.IsPost(reqMethod) || HttpMethods.IsPut(reqMethod) || HttpMethods.IsDelete(reqMethod))
{

View File

@ -195,6 +195,7 @@ Vue 版前端技术栈 :基于 vue2.x/vue3.x/uniapp、vuex、vue-router 、vue
- 👉SqlSugar[SqlSugar](https://gitee.com/dotnetchina/SqlSugar)
- 👉vue-element-admin[vue-element-admin](https://github.com/PanJiaChen/vue-element-admin)
- 👉Meiam.System[Meiam.System](https://github.com/91270/Meiam.System)
- 👉Furion[Furion](https://gitee.com/dotnetchina/Furion)
## 🎀 捐赠

View File

@ -79,13 +79,14 @@ namespace ZR.Admin.WebApi.Controllers.System
{
return ToResponse(ResultCode.LOGIN_ERROR, $"你的账号已被锁,剩余{Math.Round(ts.TotalMinutes, 0)}分钟");
}
var user = sysLoginService.Login(loginBody, RecordLogInfo(httpContextAccessor.HttpContext));
string location = HttpContextExtension.GetIpInfo(loginBody.LoginIP);
var user = sysLoginService.Login(loginBody, new SysLogininfor() { LoginLocation = location });
List<SysRole> roles = roleService.SelectUserRoleListByUserId(user.UserId);
//权限集合 eg *:*:*,system:user:list
List<string> permissions = permissionService.GetMenuPermission(user);
LoginUser loginUser = new(user, roles);
LoginUser loginUser = new(user, roles.Adapt<List<Roles>>());
CacheService.SetUserPerms(GlobalConstant.UserPermKEY + user.UserId, permissions);
return SUCCESS(JwtUtil.GenerateJwtToken(JwtUtil.AddClaims(loginUser)));
}
@ -128,8 +129,6 @@ namespace ZR.Admin.WebApi.Controllers.System
List<string> permissions = permissionService.GetMenuPermission(user);
user.WelcomeContent = GlobalConstant.WelcomeMessages[new Random().Next(0, GlobalConstant.WelcomeMessages.Length)];
//LoginUser loginUser = new(user, roleService.SelectUserRoleListByUserId(user.UserId), permissions);
//var token = JwtUtil.GenerateJwtToken(JwtUtil.AddClaims(loginUser), optionSettings.JwtSettings);
return SUCCESS(new { user, roles, permissions });
}
@ -164,29 +163,6 @@ namespace ZR.Admin.WebApi.Controllers.System
return SUCCESS(obj);
}
/// <summary>
/// 记录用户登陆信息
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
[ApiExplorerSettings(IgnoreApi = true)]
public SysLogininfor RecordLogInfo(HttpContext context)
{
var ipAddr = context.GetClientUserIp();
var ip_info = IpTool.Search(ipAddr);
ClientInfo clientInfo = context.GetClientInfo();
SysLogininfor sysLogininfor = new()
{
Browser = clientInfo.ToString(),
Os = clientInfo.OS.ToString(),
Ipaddr = ipAddr,
UserName = context.GetName(),
LoginLocation = ip_info?.Province + "-" + ip_info?.City
};
return sysLogininfor;
}
/// <summary>
/// 注册
/// </summary>

View File

@ -1,5 +1,4 @@
using Infrastructure.Extensions;
using IPTools.Core;
using IPTools.Core;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
@ -26,9 +25,7 @@ namespace ZR.Admin.WebApi.Filters
/// <returns></returns>
public override Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
{
ApiResult response = new();
response.Code = (int)ResultCode.PARAM_ERROR;
string msg = string.Empty;
var values = context.ModelState.Values;
foreach (var item in values)
{
@ -38,17 +35,22 @@ namespace ZR.Admin.WebApi.Filters
{
return next();
}
if (!string.IsNullOrEmpty(response.Msg))
if (!string.IsNullOrEmpty(msg))
{
response.Msg += " | ";
msg += " | ";
}
response.Msg += err.ErrorMessage;
msg += err.ErrorMessage;
}
}
if (!string.IsNullOrEmpty(response.Msg))
if (!string.IsNullOrEmpty(msg))
{
logger.Info($"请求参数错误,{response.Msg}");
logger.Info($"请求参数错误,{msg}");
ApiResult response = new()
{
Code = (int)ResultCode.PARAM_ERROR,
Msg = msg
};
context.Result = new JsonResult(response);
}
return base.OnActionExecutionAsync(context, next);
@ -98,7 +100,7 @@ namespace ZR.Admin.WebApi.Filters
OperUrl = HttpContextExtension.GetRequestUrl(context.HttpContext),
RequestMethod = method,
JsonResult = jsonResult,
OperLocation = ip_info.Province + " " + ip_info.City,
OperLocation = HttpContextExtension.GetIpInfo(ip),
Method = controller + "." + action + "()",
//Elapsed = _stopwatch.ElapsedMilliseconds,
OperTime = DateTime.Now,

View File

@ -1,8 +1,13 @@
using Microsoft.IdentityModel.Tokens;
using JinianNet.JNTemplate;
using JinianNet.JNTemplate.Nodes;
using Microsoft.AspNetCore.SignalR;
using Microsoft.Extensions.Caching.Memory;
using Microsoft.IdentityModel.Tokens;
using Newtonsoft.Json;
using System.IdentityModel.Tokens.Jwt;
using System.Security.Claims;
using System.Text;
using ZR.Admin.WebApi.Hubs;
using ZR.Model.System.Dto;
namespace ZR.Admin.WebApi.Framework
@ -122,7 +127,8 @@ namespace ZR.Admin.WebApi.Framework
{
try
{
IEnumerable<Claim> claims = jwtSecurityToken.Claims;
if (jwtSecurityToken == null) return null;
IEnumerable<Claim> claims = jwtSecurityToken?.Claims;
LoginUser loginUser = null;
var userData = claims.FirstOrDefault(x => x.Type == ClaimTypes.UserData)?.Value;
@ -131,7 +137,21 @@ namespace ZR.Admin.WebApi.Framework
loginUser = JsonConvert.DeserializeObject<LoginUser>(userData);
loginUser.ExpireTime = jwtSecurityToken.ValidTo;
}
//Console.WriteLine("jwt到期时间" + validTo);
//var nowTime = DateTime.UtcNow;
//TimeSpan ts = loginUser.ExpireTime - nowTime;
//Console.WriteLine("jwt到期时间" + loginUser.ExpireTime);
//Console.WriteLine("nowTime" + nowTime + ",相隔" + ts.TotalSeconds);
//if (loginUser != null && ts.TotalSeconds <= 30)
//{
// var newToken = GenerateJwtToken(AddClaims(loginUser));
// var CK = "token_" + loginUser.UserId;
// if (!CacheHelper.Exists(CK))
// {
// CacheHelper.SetCache(CK, newToken);
// }
//}
return loginUser;
}
catch (Exception ex)

View File

@ -10,6 +10,7 @@ using ZR.Admin.WebApi.Framework;
using ZR.Admin.WebApi.Hubs;
using ZR.Admin.WebApi.Middleware;
using ZR.Common.Cache;
using ZR.Model.System.Dto;
var builder = WebApplication.CreateBuilder(args);
@ -54,11 +55,12 @@ builder.Services.AddAuthentication(options =>
// 如果过期,把过期信息添加到头部
if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
{
Console.WriteLine("jwt过期了");
context.Response.Headers.Add("Token-Expired", "true");
}
return Task.CompletedTask;
}
},
};
});

View File

@ -20,7 +20,6 @@
<PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="7.0.7" />
<PackageReference Include="Swashbuckle.AspNetCore" Version="6.5.0" />
<PackageReference Include="Swashbuckle.AspNetCore.Filters" Version="7.0.6" />
<PackageReference Include="IPTools.China" Version="1.6.0" />
<PackageReference Include="NLog" Version="5.2.3" />
<PackageReference Include="NLog.Web.AspNetCore" Version="5.3.3" />
<PackageReference Include="Mapster" Version="7.3.0" />

View File

@ -17,7 +17,7 @@ namespace ZR.Model.System.Dto
/// <summary>
/// 角色集合(数据权限过滤使用)
/// </summary>
public List<SysRole> Roles { get; set; }
public List<Roles> Roles { get; set; }
/// <summary>
/// Jwt过期时间
/// </summary>
@ -30,7 +30,7 @@ namespace ZR.Model.System.Dto
{
}
public LoginUser(SysUser user, List<SysRole> roles)
public LoginUser(SysUser user, List<Roles> roles)
{
UserId = user.UserId;
UserName = user.UserName;
@ -39,4 +39,11 @@ namespace ZR.Model.System.Dto
RoleIds = roles.Select(f => f.RoleKey).ToList();
}
}
public class Roles
{
public long RoleId { get; set; }
public string RoleKey { get; set; }
public int DataScope { get; set; }
}
}

View File

@ -1,9 +1,6 @@
using System;
using System.Collections.Generic;
using System.Text;
using ZR.Model;
using ZR.Model.System.Dto;
using ZR.Model;
using ZR.Model.System;
using ZR.Model.System.Dto;
namespace ZR.Service.System.IService
{

View File

@ -1,8 +1,11 @@
using Infrastructure;
using Infrastructure.Attribute;
using Infrastructure.Extensions;
using Infrastructure.WebExtensins;
using Microsoft.AspNetCore.Http;
using SqlSugar;
using System;
using UAParser;
using ZR.Model;
using ZR.Model.System;
using ZR.Model.System.Dto;
@ -15,13 +18,15 @@ namespace ZR.Service.System
/// 登录
/// </summary>
[AppService(ServiceType = typeof(ISysLoginService), ServiceLifetime = LifeTime.Transient)]
public class SysLoginService: BaseService<SysLogininfor>, ISysLoginService
public class SysLoginService : BaseService<SysLogininfor>, ISysLoginService
{
private readonly ISysUserService SysUserService;
private readonly IHttpContextAccessor httpContextAccessor;
public SysLoginService(ISysUserService sysUserService)
public SysLoginService(ISysUserService sysUserService, IHttpContextAccessor httpContextAccessor)
{
SysUserService = sysUserService;
this.httpContextAccessor = httpContextAccessor;
}
/// <summary>
@ -35,17 +40,21 @@ namespace ZR.Service.System
{
loginBody.Password = NETCore.Encrypt.EncryptProvider.Md5(loginBody.Password);
}
SysUser user = SysUserService.Login(loginBody);
logininfor.UserName = loginBody.Username;
logininfor.Status = "1";
logininfor.LoginTime = DateTime.Now;
logininfor.Ipaddr = loginBody.LoginIP;
ClientInfo clientInfo = httpContextAccessor.HttpContext.GetClientInfo();
logininfor.Browser = clientInfo.ToString();
logininfor.Os = clientInfo.OS.ToString();
if (user == null || user.UserId <= 0)
{
logininfor.Msg = "用户名或密码错误";
AddLoginInfo(logininfor);
throw new CustomException(ResultCode.LOGIN_ERROR ,logininfor.Msg);
throw new CustomException(ResultCode.LOGIN_ERROR, logininfor.Msg);
}
if (user.Status == 1)
{