update 验证密码强度,并修改密码,在debug模式下登录不需要正确密码

This commit is contained in:
2021-07-02 19:00:01 +08:00
parent fda3e8e8f2
commit 36a9964899
8 changed files with 274 additions and 50 deletions

View File

@@ -3228,122 +3228,132 @@
</summary>
<example>123456</example>
</member>
<member name="T:Ewide.Core.Service.LoginOutput">
<member name="P:Ewide.Core.Service.LoginPassInput.NewPassword">
<summary>
新密码
</summary>
</member>
<member name="P:Ewide.Core.Service.LoginPassInput.Confirm">
<summary>
确认密码
</summary>
</member>
<member name="T:Ewide.Core.Service.LoginUserOutput">
<summary>
用户登录输出参数
</summary>
</member>
<member name="P:Ewide.Core.Service.LoginOutput.Id">
<member name="P:Ewide.Core.Service.LoginUserOutput.Id">
<summary>
主键
</summary>
</member>
<member name="P:Ewide.Core.Service.LoginOutput.Account">
<member name="P:Ewide.Core.Service.LoginUserOutput.Account">
<summary>
账号
</summary>
</member>
<member name="P:Ewide.Core.Service.LoginOutput.SecurityLevel">
<member name="P:Ewide.Core.Service.LoginUserOutput.SecurityLevel">
<summary>
密码安全级别
</summary>
</member>
<member name="P:Ewide.Core.Service.LoginOutput.NickName">
<member name="P:Ewide.Core.Service.LoginUserOutput.NickName">
<summary>
昵称
</summary>
</member>
<member name="P:Ewide.Core.Service.LoginOutput.Name">
<member name="P:Ewide.Core.Service.LoginUserOutput.Name">
<summary>
姓名
</summary>
</member>
<member name="P:Ewide.Core.Service.LoginOutput.Avatar">
<member name="P:Ewide.Core.Service.LoginUserOutput.Avatar">
<summary>
头像
</summary>
</member>
<member name="P:Ewide.Core.Service.LoginOutput.Birthday">
<member name="P:Ewide.Core.Service.LoginUserOutput.Birthday">
<summary>
生日
</summary>
</member>
<member name="P:Ewide.Core.Service.LoginOutput.Sex">
<member name="P:Ewide.Core.Service.LoginUserOutput.Sex">
<summary>
性别(字典 1男 2女)
</summary>
</member>
<member name="P:Ewide.Core.Service.LoginOutput.Email">
<member name="P:Ewide.Core.Service.LoginUserOutput.Email">
<summary>
邮箱
</summary>
</member>
<member name="P:Ewide.Core.Service.LoginOutput.Phone">
<member name="P:Ewide.Core.Service.LoginUserOutput.Phone">
<summary>
手机
</summary>
</member>
<member name="P:Ewide.Core.Service.LoginOutput.Tel">
<member name="P:Ewide.Core.Service.LoginUserOutput.Tel">
<summary>
电话
</summary>
</member>
<member name="P:Ewide.Core.Service.LoginOutput.AdminType">
<member name="P:Ewide.Core.Service.LoginUserOutput.AdminType">
<summary>
管理员类型0超级管理员 1非管理员
</summary>
</member>
<member name="P:Ewide.Core.Service.LoginOutput.LastLoginIp">
<member name="P:Ewide.Core.Service.LoginUserOutput.LastLoginIp">
<summary>
最后登陆IP
</summary>
</member>
<member name="P:Ewide.Core.Service.LoginOutput.LastLoginTime">
<member name="P:Ewide.Core.Service.LoginUserOutput.LastLoginTime">
<summary>
最后登陆时间
</summary>
</member>
<member name="P:Ewide.Core.Service.LoginOutput.LastLoginAddress">
<member name="P:Ewide.Core.Service.LoginUserOutput.LastLoginAddress">
<summary>
最后登陆地址
</summary>
</member>
<member name="P:Ewide.Core.Service.LoginOutput.LastLoginBrowser">
<member name="P:Ewide.Core.Service.LoginUserOutput.LastLoginBrowser">
<summary>
最后登陆所用浏览器
</summary>
</member>
<member name="P:Ewide.Core.Service.LoginOutput.LastLoginOs">
<member name="P:Ewide.Core.Service.LoginUserOutput.LastLoginOs">
<summary>
最后登陆所用系统
</summary>
</member>
<member name="P:Ewide.Core.Service.LoginOutput.LoginEmpInfo">
<member name="P:Ewide.Core.Service.LoginUserOutput.LoginEmpInfo">
<summary>
员工信息
</summary>
</member>
<member name="P:Ewide.Core.Service.LoginOutput.Apps">
<member name="P:Ewide.Core.Service.LoginUserOutput.Apps">
<summary>
具备应用信息
</summary>
</member>
<member name="P:Ewide.Core.Service.LoginOutput.Roles">
<member name="P:Ewide.Core.Service.LoginUserOutput.Roles">
<summary>
角色信息
</summary>
</member>
<member name="P:Ewide.Core.Service.LoginOutput.Permissions">
<member name="P:Ewide.Core.Service.LoginUserOutput.Permissions">
<summary>
权限信息
</summary>
</member>
<member name="P:Ewide.Core.Service.LoginOutput.Menus">
<member name="P:Ewide.Core.Service.LoginUserOutput.Menus">
<summary>
登录菜单信息---AntDesign版本菜单
</summary>
</member>
<member name="P:Ewide.Core.Service.LoginOutput.DataScopes">
<member name="P:Ewide.Core.Service.LoginUserOutput.DataScopes">
<summary>
数据范围(机构)信息
</summary>

View File

@@ -14,6 +14,7 @@ using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using UAParser;
@@ -68,20 +69,90 @@ namespace Ewide.Core.Service
/// <returns></returns>
[HttpPost("/login")]
[AllowAnonymous]
public async Task<string> LoginAsync([Required] LoginInput input)
public async Task<LoginOutput> LoginAsync([Required] LoginInput input)
{
string pwd = RSAHandler.RSADecrypt(input.Password);
// 获取加密后的密码
var encryptPasswod = MD5Encryption.Encrypt(pwd);
var password = RSAHandler.RSADecrypt(input.Password);
var user = await GetUser(input);
#if !DEBUG
// 验证密码强度
var pattern = App.Configuration.GetSection("SimplePassword:Pattern").Value;
if (!Regex.Match(password, pattern).Success)
{
return new LoginOutput
{
Passed = false,
Pattern = pattern,
Descriptions = App.Configuration.GetSection("SimplePassword:Descriptions").Value
};
}
#endif
return new LoginOutput
{
Passed = true,
Token = await HandlerLoginAsync(user)
};
}
[HttpPost("/loginPass")]
[AllowAnonymous]
public async Task<LoginOutput> LoginPassAsync([Required] LoginPassInput input)
{
var user = await GetUser(input);
var newPassword = RSAHandler.RSADecrypt(input.NewPassword);
// 验证新密码强度
var pattern = App.Configuration.GetSection("SimplePassword:Pattern").Value;
if (!Regex.Match(newPassword, pattern).Success)
{
return new LoginOutput
{
Passed = false,
Pattern = pattern,
Descriptions = App.Configuration.GetSection("SimplePassword:Descriptions").Value
};
}
newPassword = MD5Encryption.Encrypt(newPassword);
if (newPassword.Equals(user.Password))
throw Oops.Oh(ErrorCode.D10041);
user.Password = newPassword;
return new LoginOutput
{
Passed = true,
Token = await HandlerLoginAsync(user)
};
}
private async Task<SysUser> GetUser(LoginInput input)
{
var password = RSAHandler.RSADecrypt(input.Password);
// 获取加密后的密码
var encryptPasswod = MD5Encryption.Encrypt(password);
#if DEBUG
var user = await _sysUserRep.FirstOrDefaultAsync(u => u.Account.Equals(input.Account));
#else
// 判断用户名和密码是否正确
var user = await _sysUserRep.FirstOrDefaultAsync(u => u.Account.Equals(input.Account) && u.Password.Equals(encryptPasswod));
_ = user ?? throw Oops.Oh(ErrorCode.D1000);
#endif
// 验证账号是否被冻结
if (user.Status == CommonStatus.DISABLE)
throw Oops.Oh(ErrorCode.D1017);
return user;
}
private async Task<string> HandlerLoginAsync(SysUser user)
{
// 生成Token令牌
//var accessToken = await _jwtBearerManager.CreateTokenAdmin(user);
var accessToken = JWTEncryption.Encrypt(new Dictionary<string, object>
@@ -102,38 +173,40 @@ namespace Ewide.Core.Service
_httpContextAccessor.HttpContext.Response.Headers["x-access-token"] = refreshToken;
// 增加登录日志
var loginOutput = user.Adapt<LoginOutput>();
var loginUserOutput = user.Adapt<LoginUserOutput>();
var clent = Parser.GetDefault().Parse(App.GetService<IHttpContextAccessor>().HttpContext.Request.Headers["User-Agent"]);
loginOutput.LastLoginBrowser = clent.UA.Family + clent.UA.Major;
loginOutput.LastLoginOs = clent.OS.Family + clent.OS.Major;
loginUserOutput.LastLoginBrowser = clent.UA.Family + clent.UA.Major;
loginUserOutput.LastLoginOs = clent.OS.Family + clent.OS.Major;
await new SysLogVis
{
Name = "登录",
Success = true,
Message = "登录成功",
Ip = loginOutput.LastLoginIp,
Browser = loginOutput.LastLoginBrowser,
Os = loginOutput.LastLoginOs,
Ip = loginUserOutput.LastLoginIp,
Browser = loginUserOutput.LastLoginBrowser,
Os = loginUserOutput.LastLoginOs,
VisType = 1,
VisTime = loginOutput.LastLoginTime,
Account = loginOutput.Account
VisTime = loginUserOutput.LastLoginTime,
Account = loginUserOutput.Account
}.InsertAsync();
return accessToken;
}
/// <summary>
/// 获取当前登录用户信息
/// </summary>
/// <returns></returns>
[HttpGet("/getLoginUser")]
public async Task<LoginOutput> GetLoginUserAsync()
public async Task<LoginUserOutput> GetLoginUserAsync()
{
var user = _userManager.User;
var userId = user.Id;
var httpContext = App.GetService<IHttpContextAccessor>().HttpContext;
var loginOutput = user.Adapt<LoginOutput>();
var loginOutput = user.Adapt<LoginUserOutput>();
// 隐藏手机号/邮箱中间几位
loginOutput.Phone = String.IsNullOrEmpty(loginOutput.Phone) ? loginOutput.Phone
@@ -197,7 +270,7 @@ namespace Ewide.Core.Service
var userId = user.Id;
var httpContext = App.GetService<IHttpContextAccessor>().HttpContext;
var loginOutput = user.Adapt<LoginOutput>();
var loginOutput = user.Adapt<LoginUserOutput>();
var ip = httpContext.Request.Headers["X-Real-IP"];

View File

@@ -1,4 +1,5 @@
using Furion.DependencyInjection;
using Furion;
using Furion.DependencyInjection;
using System.ComponentModel.DataAnnotations;
namespace Ewide.Core.Service
@@ -14,13 +15,29 @@ namespace Ewide.Core.Service
/// </summary>
/// <example>superAdmin</example>
[Required(ErrorMessage = "用户名不能为空"), MinLength(3, ErrorMessage = "用户名不能少于3位字符")]
public string Account { get; set; }
public virtual string Account { get; set; }
/// <summary>
/// 密码
/// </summary>
/// <example>123456</example>
[Required(ErrorMessage = "密码不能为空"), MinLength(5, ErrorMessage = "密码不能少于5位字符")]
public string Password { get; set; }
public virtual string Password { get; set; }
}
[SkipScan]
public class LoginPassInput : LoginInput
{
/// <summary>
/// 新密码
/// </summary>
[Required(ErrorMessage = "新密码不能为空")]
public string NewPassword { get; set; }
/// <summary>
/// 确认密码
/// </summary>
[Required(ErrorMessage = "确认密码不能为空"), Compare(nameof(NewPassword), ErrorMessage = "两次密码不一致")]
public string Confirm { get; set; }
}
}

View File

@@ -4,11 +4,20 @@ using System.Collections.Generic;
namespace Ewide.Core.Service
{
[SkipScan]
public class LoginOutput
{
public bool Passed { get; set; }
public string Pattern { get; set; }
public string Descriptions { get; set; }
public string Token { get; set; }
}
/// <summary>
/// 用户登录输出参数
/// </summary>
[SkipScan]
public class LoginOutput
public class LoginUserOutput
{
/// <summary>
/// 主键

View File

@@ -7,8 +7,8 @@ namespace Ewide.Core.Service
{
Task<dynamic> GetCaptcha();
Task<bool> GetCaptchaOpen();
Task<LoginOutput> GetLoginUserAsync();
Task<string> LoginAsync([Required] LoginInput input);
Task<LoginUserOutput> GetLoginUserAsync();
Task<LoginOutput> LoginAsync([Required] LoginInput input);
Task LogoutAsync();
Task<dynamic> VerificationCode(ClickWordCaptchaInput input);
}

View File

@@ -102,5 +102,10 @@
"sysNotice:unread",
"sysNotice:detail"
]
},
"SimplePassword": {
"Pattern": "(?=.*[0-9])(?=.*[A-Z])(?=.*[a-z])(?=.*[^a-zA-Z0-9]){8,}",
"Descriptions": "密码中必须包含大小字母、数字、特称字符至少8个字符"
}
}