✨新增手机号登录功能
This commit is contained in:
parent
f859748825
commit
df36de52fa
25
Infrastructure/Helper/RandomHelper.cs
Normal file
25
Infrastructure/Helper/RandomHelper.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace ZR.Infrastructure.Helper
|
||||||
|
{
|
||||||
|
public class RandomHelper
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 生成n为验证码
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="Length"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public static string GenerateNum(int Length)
|
||||||
|
{
|
||||||
|
char[] constant = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
|
||||||
|
StringBuilder newRandom = new(constant.Length);
|
||||||
|
Random rd = new();
|
||||||
|
for (int i = 0; i < Length; i++)
|
||||||
|
{
|
||||||
|
newRandom.Append(constant[rd.Next(constant.Length - 1)]);
|
||||||
|
}
|
||||||
|
return newRandom.ToString();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,10 +1,13 @@
|
|||||||
using Lazy.Captcha.Core;
|
using Lazy.Captcha.Core;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using ZR.Admin.WebApi.Filters;
|
using ZR.Admin.WebApi.Filters;
|
||||||
|
using ZR.Infrastructure.Helper;
|
||||||
using ZR.Model.System;
|
using ZR.Model.System;
|
||||||
using ZR.Model.System.Dto;
|
using ZR.Model.System.Dto;
|
||||||
using ZR.Service.System;
|
using ZR.Service.System;
|
||||||
using ZR.Service.System.IService;
|
using ZR.Service.System.IService;
|
||||||
|
using ZR.ServiceCore.Model.Dto;
|
||||||
|
using ZR.ServiceCore.Services;
|
||||||
|
|
||||||
namespace ZR.Admin.WebApi.Controllers.System
|
namespace ZR.Admin.WebApi.Controllers.System
|
||||||
{
|
{
|
||||||
@ -21,6 +24,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
private readonly ICaptcha SecurityCodeHelper;
|
private readonly ICaptcha SecurityCodeHelper;
|
||||||
private readonly ISysConfigService sysConfigService;
|
private readonly ISysConfigService sysConfigService;
|
||||||
private readonly ISysRoleService roleService;
|
private readonly ISysRoleService roleService;
|
||||||
|
private readonly ISmsCodeLogService smsCodeLogService;
|
||||||
|
|
||||||
public SysLoginController(
|
public SysLoginController(
|
||||||
ISysMenuService sysMenuService,
|
ISysMenuService sysMenuService,
|
||||||
@ -29,6 +33,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
ISysPermissionService permissionService,
|
ISysPermissionService permissionService,
|
||||||
ISysConfigService configService,
|
ISysConfigService configService,
|
||||||
ISysRoleService sysRoleService,
|
ISysRoleService sysRoleService,
|
||||||
|
ISmsCodeLogService smsCodeLogService,
|
||||||
ICaptcha captcha)
|
ICaptcha captcha)
|
||||||
{
|
{
|
||||||
SecurityCodeHelper = captcha;
|
SecurityCodeHelper = captcha;
|
||||||
@ -37,6 +42,7 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
this.sysLoginService = sysLoginService;
|
this.sysLoginService = sysLoginService;
|
||||||
this.permissionService = permissionService;
|
this.permissionService = permissionService;
|
||||||
this.sysConfigService = configService;
|
this.sysConfigService = configService;
|
||||||
|
this.smsCodeLogService = smsCodeLogService;
|
||||||
roleService = sysRoleService;
|
roleService = sysRoleService;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -253,5 +259,73 @@ namespace ZR.Admin.WebApi.Controllers.System
|
|||||||
}
|
}
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
///
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="dto"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[HttpPost("checkMobile")]
|
||||||
|
[Log(Title = "发送短息", BusinessType = BusinessType.INSERT)]
|
||||||
|
public IActionResult CheckMobile([FromBody] PhoneLoginDto dto)
|
||||||
|
{
|
||||||
|
dto.LoginIP = HttpContextExtension.GetClientUserIp(HttpContext);
|
||||||
|
|
||||||
|
SysConfig sysConfig = sysConfigService.GetSysConfigByKey("sys.account.captchaOnOff");
|
||||||
|
if (sysConfig?.ConfigValue != "off" && !SecurityCodeHelper.Validate(dto.Uuid, dto.Code, false))
|
||||||
|
{
|
||||||
|
return ToResponse(ResultCode.CUSTOM_ERROR, "验证码错误");
|
||||||
|
}
|
||||||
|
string location = HttpContextExtension.GetIpInfo(dto.LoginIP);
|
||||||
|
var info = sysUserService.GetFirst(f => f.Phonenumber == dto.PhoneNum) ?? throw new CustomException(ResultCode.CUSTOM_ERROR, "该手机号不存在", false);
|
||||||
|
|
||||||
|
var smsCode = RandomHelper.GenerateNum(6);
|
||||||
|
var smsContent = $"验证码{smsCode}(随机验证码),有效期10分钟。";
|
||||||
|
//TODO 发送短息验证码,1分钟内允许一次
|
||||||
|
smsCodeLogService.AddSmscodeLog(new ServiceCore.Model.SmsCodeLog()
|
||||||
|
{
|
||||||
|
Userid = info.UserId,
|
||||||
|
PhoneNum = dto.PhoneNum.ParseToLong(),
|
||||||
|
AddTime = DateTime.Now,
|
||||||
|
SendType = 1,
|
||||||
|
SmsCode = smsCode,
|
||||||
|
SmsContent = smsContent,
|
||||||
|
UserIP = dto.LoginIP,
|
||||||
|
Location = location,
|
||||||
|
});
|
||||||
|
CacheService.SetPhoneCode(dto.PhoneNum, smsCode);
|
||||||
|
|
||||||
|
return SUCCESS(new { smsCode });
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 手机号登录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="loginBody">登录对象</param>
|
||||||
|
/// <returns></returns>
|
||||||
|
[Route("PhoneLogin")]
|
||||||
|
[HttpPost]
|
||||||
|
[Log(Title = "手机号登录")]
|
||||||
|
public IActionResult PhoneLogin([FromBody] PhoneLoginDto loginBody)
|
||||||
|
{
|
||||||
|
if (loginBody == null) { throw new CustomException("请求参数错误"); }
|
||||||
|
loginBody.LoginIP = HttpContextExtension.GetClientUserIp(HttpContext);
|
||||||
|
|
||||||
|
if (!CacheService.CheckPhoneCode(loginBody.PhoneNum, loginBody.PhoneCode))
|
||||||
|
{
|
||||||
|
return ToResponse(ResultCode.CUSTOM_ERROR, "短信验证码错误");
|
||||||
|
}
|
||||||
|
var info = sysUserService.GetFirst(f => f.Phonenumber == loginBody.PhoneNum) ?? throw new CustomException(ResultCode.CUSTOM_ERROR, "该手机号不存在", false);
|
||||||
|
sysLoginService.CheckLockUser(info.UserName);
|
||||||
|
string location = HttpContextExtension.GetIpInfo(loginBody.LoginIP);
|
||||||
|
var user = sysLoginService.PhoneLogin(loginBody, new SysLogininfor() { LoginLocation = location }, info);
|
||||||
|
|
||||||
|
List<SysRole> roles = roleService.SelectUserRoleListByUserId(user.UserId);
|
||||||
|
//权限集合 eg *:*:*,system:user:list
|
||||||
|
List<string> permissions = permissionService.GetMenuPermission(user);
|
||||||
|
|
||||||
|
TokenModel loginUser = new(user.Adapt<TokenModel>(), roles.Adapt<List<Roles>>());
|
||||||
|
CacheService.SetUserPerms(GlobalConstant.UserPermKEY + user.UserId, permissions);
|
||||||
|
return SUCCESS(JwtUtil.GenerateJwtToken(JwtUtil.AddClaims(loginUser)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,5 +1,6 @@
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using ZR.Admin.WebApi.Filters;
|
using ZR.Admin.WebApi.Filters;
|
||||||
|
using ZR.Infrastructure.Helper;
|
||||||
using ZR.Model.System;
|
using ZR.Model.System;
|
||||||
using ZR.Model.System.Dto;
|
using ZR.Model.System.Dto;
|
||||||
using ZR.Service.System.IService;
|
using ZR.Service.System.IService;
|
||||||
|
|||||||
Binary file not shown.
25
ZR.ServiceCore/Model/Dto/PhoneLoginDto.cs
Normal file
25
ZR.ServiceCore/Model/Dto/PhoneLoginDto.cs
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
using System.ComponentModel.DataAnnotations;
|
||||||
|
|
||||||
|
namespace ZR.ServiceCore.Model.Dto
|
||||||
|
{
|
||||||
|
public class PhoneLoginDto
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// 验证码
|
||||||
|
/// </summary>
|
||||||
|
public string Code { get; set; }
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// 唯一标识
|
||||||
|
/// </summary>
|
||||||
|
public string Uuid { get; set; } = "";
|
||||||
|
public string LoginIP { get; set; }
|
||||||
|
[Required(ErrorMessage = "手机号不能为空")]
|
||||||
|
public string PhoneNum { get; set; }
|
||||||
|
/// <summary>
|
||||||
|
/// 手机短信验证码
|
||||||
|
/// </summary>
|
||||||
|
//[Required(ErrorMessage = "短信验证码不能为空")]
|
||||||
|
public string PhoneCode { get; set; }
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,11 +1,11 @@
|
|||||||
using System;
|
using ZR.Common;
|
||||||
using ZR.Common;
|
|
||||||
|
|
||||||
namespace ZR.Service.System
|
namespace ZR.Service.System
|
||||||
{
|
{
|
||||||
public class CacheService
|
public class CacheService
|
||||||
{
|
{
|
||||||
private readonly static string CK_verifyScan = "verifyScan_";
|
private readonly static string CK_verifyScan = "verifyScan_";
|
||||||
|
private readonly static string CK_phoneSmsCode = "phone_sms_code_";
|
||||||
#region 用户权限 缓存
|
#region 用户权限 缓存
|
||||||
public static List<string> GetUserPerms(string key)
|
public static List<string> GetUserPerms(string key)
|
||||||
{
|
{
|
||||||
@ -59,5 +59,23 @@ namespace ZR.Service.System
|
|||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static object SetPhoneCode(string key, string val)
|
||||||
|
{
|
||||||
|
var ck = CK_phoneSmsCode + key;
|
||||||
|
|
||||||
|
return CacheHelper.SetCache(ck, val, 10);
|
||||||
|
}
|
||||||
|
public static bool CheckPhoneCode(string key, string val)
|
||||||
|
{
|
||||||
|
var ck = CK_phoneSmsCode + key;
|
||||||
|
var save_code = CacheHelper.Get(ck);
|
||||||
|
|
||||||
|
if (save_code != null && save_code.Equals(val))
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
using Infrastructure;
|
using ZR.Model;
|
||||||
using System;
|
|
||||||
using ZR.Model;
|
|
||||||
using ZR.Model.System;
|
using ZR.Model.System;
|
||||||
using ZR.Model.System.Dto;
|
using ZR.Model.System.Dto;
|
||||||
|
using ZR.ServiceCore.Model.Dto;
|
||||||
|
|
||||||
namespace ZR.Service.System.IService
|
namespace ZR.Service.System.IService
|
||||||
{
|
{
|
||||||
@ -15,7 +14,14 @@ namespace ZR.Service.System.IService
|
|||||||
/// <param name="logininfor"></param>
|
/// <param name="logininfor"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public SysUser Login(LoginBodyDto loginBody, SysLogininfor logininfor);
|
public SysUser Login(LoginBodyDto loginBody, SysLogininfor logininfor);
|
||||||
|
/// <summary>
|
||||||
|
/// 手机号登录
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="loginBody"></param>
|
||||||
|
/// <param name="logininfor"></param>
|
||||||
|
/// <param name="user"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
SysUser PhoneLogin(PhoneLoginDto loginBody, SysLogininfor logininfor, SysUser user);
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查询操作日志
|
/// 查询操作日志
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -81,6 +81,6 @@ namespace ZR.Service.System.IService
|
|||||||
|
|
||||||
SysUser Login(LoginBodyDto user);
|
SysUser Login(LoginBodyDto user);
|
||||||
|
|
||||||
void UpdateLoginInfo(LoginBodyDto user, long userId);
|
void UpdateLoginInfo(string userIP, long userId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,6 +1,5 @@
|
|||||||
using Infrastructure;
|
using Infrastructure;
|
||||||
using Infrastructure.Attribute;
|
using Infrastructure.Attribute;
|
||||||
using Infrastructure.Extensions;
|
|
||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using UAParser;
|
using UAParser;
|
||||||
using ZR.Model;
|
using ZR.Model;
|
||||||
@ -8,6 +7,7 @@ using ZR.Model.System;
|
|||||||
using ZR.Model.System.Dto;
|
using ZR.Model.System.Dto;
|
||||||
using ZR.Repository;
|
using ZR.Repository;
|
||||||
using ZR.Service.System.IService;
|
using ZR.Service.System.IService;
|
||||||
|
using ZR.ServiceCore.Model.Dto;
|
||||||
|
|
||||||
namespace ZR.Service.System
|
namespace ZR.Service.System
|
||||||
{
|
{
|
||||||
@ -64,10 +64,40 @@ namespace ZR.Service.System
|
|||||||
logininfor.Status = "0";
|
logininfor.Status = "0";
|
||||||
logininfor.Msg = "登录成功";
|
logininfor.Msg = "登录成功";
|
||||||
AddLoginInfo(logininfor);
|
AddLoginInfo(logininfor);
|
||||||
SysUserService.UpdateLoginInfo(loginBody, user.UserId);
|
SysUserService.UpdateLoginInfo(loginBody.LoginIP, user.UserId);
|
||||||
return user;
|
return user;
|
||||||
}
|
}
|
||||||
|
/// <summary>
|
||||||
|
/// 登录验证
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="logininfor"></param>
|
||||||
|
/// <param name="loginBody"></param>
|
||||||
|
/// <param name="user"></param>
|
||||||
|
/// <returns></returns>
|
||||||
|
public SysUser PhoneLogin(PhoneLoginDto loginBody, SysLogininfor logininfor, SysUser user)
|
||||||
|
{
|
||||||
|
logininfor.UserName = user.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.Status == 1)
|
||||||
|
{
|
||||||
|
logininfor.Msg = "该用户已禁用";
|
||||||
|
AddLoginInfo(logininfor);
|
||||||
|
throw new CustomException(ResultCode.LOGIN_ERROR, logininfor.Msg, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
logininfor.Status = "0";
|
||||||
|
logininfor.Msg = "登录成功";
|
||||||
|
AddLoginInfo(logininfor);
|
||||||
|
SysUserService.UpdateLoginInfo(loginBody.LoginIP, user.UserId);
|
||||||
|
return user;
|
||||||
|
}
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// 查询登录日志
|
/// 查询登录日志
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@ -329,12 +329,12 @@ namespace ZR.Service
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// 修改登录信息
|
/// 修改登录信息
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="user"></param>
|
/// <param name="userIP"></param>
|
||||||
/// <param name="userId"></param>
|
/// <param name="userId"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public void UpdateLoginInfo(LoginBodyDto user, long userId)
|
public void UpdateLoginInfo(string userIP, long userId)
|
||||||
{
|
{
|
||||||
Update(new SysUser() { LoginIP = user.LoginIP, LoginDate = DateTime.Now, UserId = userId }, it => new { it.LoginIP, it.LoginDate });
|
Update(new SysUser() { LoginIP = userIP, LoginDate = DateTime.Now, UserId = userId }, it => new { it.LoginIP, it.LoginDate });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user