From 6533020ebcb2a66f12cec0951bafaee26b9bd0d6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?=E4=B8=8D=E5=81=9A=E7=A0=81=E5=86=9C?= <599854767@qq.com>
Date: Sat, 26 Aug 2023 15:54:41 +0800
Subject: [PATCH] =?UTF-8?q?:sparkles:=E6=96=B0=E5=A2=9E=E7=A7=BB=E5=8A=A8?=
=?UTF-8?q?=E7=AB=AF=E6=89=AB=E7=A0=81=E7=99=BB=E5=BD=95?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
---
.../Extensions/HttpContextExtension.cs | 51 +++++------
Infrastructure/Infrastructure.csproj | 3 +-
.../Controllers/System/SysLoginController.cs | 87 +++++++++++++++++++
.../Filters/GlobalActionMonitor.cs | 11 +--
ZR.Admin.WebApi/Filters/VerifyAttribute.cs | 8 +-
ZR.Admin.WebApi/GlobalUsing.cs | 3 +-
.../Middleware/GlobalExceptionMiddleware.cs | 12 +--
ZR.Admin.WebApi/ZR.Admin.WebApi.csproj | 1 -
ZR.Admin.WebApi/appsettings.json | 2 +-
ZR.Model/System/Dto/LoginUser.cs | 3 +-
ZR.Model/System/Dto/ScanDto.cs | 9 ++
ZR.Service/System/CacheService.cs | 40 ++++++++-
12 files changed, 173 insertions(+), 57 deletions(-)
rename {ZR.Admin.WebApi => Infrastructure}/Extensions/HttpContextExtension.cs (92%)
create mode 100644 ZR.Model/System/Dto/ScanDto.cs
diff --git a/ZR.Admin.WebApi/Extensions/HttpContextExtension.cs b/Infrastructure/Extensions/HttpContextExtension.cs
similarity index 92%
rename from ZR.Admin.WebApi/Extensions/HttpContextExtension.cs
rename to Infrastructure/Extensions/HttpContextExtension.cs
index 542065c..6b92670 100644
--- a/ZR.Admin.WebApi/Extensions/HttpContextExtension.cs
+++ b/Infrastructure/Extensions/HttpContextExtension.cs
@@ -1,12 +1,14 @@
-using Infrastructure;
-using Infrastructure.Extensions;
+using Microsoft.AspNetCore.Http;
+using System;
+using System.Collections.Generic;
+using System.IO;
+using System.Linq;
using System.Security.Claims;
using System.Text;
using System.Text.RegularExpressions;
using UAParser;
-using ZR.Model.System;
-namespace ZR.Admin.WebApi.Extensions
+namespace Infrastructure.Extensions
{
///
/// HttpContext扩展类
@@ -82,7 +84,7 @@ namespace ZR.Admin.WebApi.Extensions
///
///
///
- public static string? GetName(this HttpContext context)
+ public static string GetName(this HttpContext context)
{
var uid = context.User?.Identity?.Name;
@@ -105,7 +107,7 @@ namespace ZR.Admin.WebApi.Extensions
///
///
///
- public static IEnumerable? GetClaims(this HttpContext context)
+ public static IEnumerable GetClaims(this HttpContext context)
{
return context.User?.Identities;
}
@@ -131,26 +133,12 @@ namespace ZR.Admin.WebApi.Extensions
return context.Request.Headers["Authorization"];
}
- ///
- /// 获取浏览器信息
- ///
- ///
- ///
- public static ClientInfo GetClientInfo(this HttpContext context)
- {
- var str = context.GetUserAgent();
- var uaParser = Parser.GetDefault();
- ClientInfo c = uaParser.Parse(str);
-
- return c;
- }
-
///
/// 获取请求Url
///
///
///
- public static string? GetRequestUrl(this HttpContext context)
+ public static string GetRequestUrl(this HttpContext context)
{
return context != null ? context.Request.Path.Value : "";
}
@@ -194,14 +182,27 @@ namespace ZR.Admin.WebApi.Extensions
return body;
}
+ ///
+ /// 获取浏览器信息
+ ///
+ ///
+ ///
+ public static ClientInfo GetClientInfo(this HttpContext context)
+ {
+ var str = context.GetUserAgent();
+ var uaParser = Parser.GetDefault();
+ ClientInfo c = uaParser.Parse(str);
+
+ return c;
+ }
+
///
/// 设置请求参数
///
- ///
+ ///
///
- public static void GetRequestValue(this HttpContext context, SysOperLog operLog)
+ public static string GetRequestValue(this HttpContext context,string reqMethod)
{
- string reqMethod = operLog.RequestMethod;
string param= string.Empty;
if (HttpMethods.IsPost(reqMethod) || HttpMethods.IsPut(reqMethod) || HttpMethods.IsDelete(reqMethod))
@@ -213,7 +214,7 @@ namespace ZR.Admin.WebApi.Extensions
{
param = context.GetQueryString();
}
- operLog.OperParam = param;
+ return param;
}
[GeneratedRegex("(?<=\"password\":\")[^\",]*")]
diff --git a/Infrastructure/Infrastructure.csproj b/Infrastructure/Infrastructure.csproj
index c305efe..d20e088 100644
--- a/Infrastructure/Infrastructure.csproj
+++ b/Infrastructure/Infrastructure.csproj
@@ -1,4 +1,4 @@
-
+
net7.0
@@ -14,6 +14,7 @@
+
diff --git a/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs b/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs
index a66cc7f..6105e69 100644
--- a/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs
+++ b/ZR.Admin.WebApi/Controllers/System/SysLoginController.cs
@@ -2,6 +2,8 @@
using Lazy.Captcha.Core;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Options;
+using SqlSugar;
+using System.Diagnostics;
using UAParser;
using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Filters;
@@ -72,6 +74,15 @@ namespace ZR.Admin.WebApi.Controllers.System
return ToResponse(ResultCode.CAPTCHA_ERROR, "验证码错误");
}
+ var lockTimeStamp = CacheService.GetLockUser(loginBody.ClientId);
+ var lockTime = DateTimeHelper.ToLocalTimeDateBySeconds(lockTimeStamp);
+ var ts = lockTime - DateTime.Now;
+
+ if (lockTimeStamp > 0 && ts.TotalSeconds > 0)
+ {
+ return ToResponse(ResultCode.LOGIN_ERROR, $"你的账号已被锁,剩余{Math.Round(ts.TotalMinutes, 0)}分钟");
+ }
+
var user = sysLoginService.Login(loginBody, RecordLogInfo(httpContextAccessor.HttpContext));
List roles = roleService.SelectUserRoleListByUserId(user.UserId);
@@ -205,5 +216,81 @@ namespace ZR.Admin.WebApi.Controllers.System
}
return ToResponse(ResultCode.CUSTOM_ERROR, "注册失败,请联系管理员");
}
+
+ #region 二维码登录
+
+ ///
+ /// 生成二维码
+ ///
+ ///
+ ///
+ ///
+ [HttpGet("/GenerateQrcode")]
+ public IActionResult GenerateQrcode(string uuid, string deviceId)
+ {
+ var state = Guid.NewGuid().ToString();
+ var dict = new Dictionary
+ {
+ { "state", state }
+ };
+ CacheService.SetScanLogin(uuid, dict);
+ return SUCCESS(new
+ {
+ status = 1,
+ state,
+ uuid,
+ codeContent = new { uuid, deviceId }// "https://qm.qq.com/cgi-bin/qm/qr?k=kgt4HsckdljU0VM-0kxND6d_igmfuPlL&authKey=r55YUbruiKQ5iwC/folG7KLCmZ++Y4rQVgNlvLbUniUMkbk24Y9+zNuOmOnjAjRc&noverify=0"
+ });
+ }
+
+ ///
+ /// 轮询判断扫码状态
+ ///
+ ///
+ ///
+ [HttpPost("/VerifyScan")]
+ [AllowAnonymous]
+ public IActionResult VerifyScan([FromBody] ScanDto dto)
+ {
+ int status = -1;
+ object token = string.Empty;
+ if (CacheService.GetScanLogin(dto.Uuid) is Dictionary str)
+ {
+ status = 0;
+ str.TryGetValue("token", out token);
+ if (str.ContainsKey("status") && (string)str.GetValueOrDefault("status") == "success")
+ {
+ status = 2;//扫码成功
+ CacheService.RemoveScanLogin(dto.Uuid);
+ }
+ }
+
+ return SUCCESS(new { status, token });
+ }
+
+ ///
+ /// 移动端扫码登录
+ ///
+ ///
+ ///
+ [HttpPost("/ScanLogin")]
+ [Log(Title = "扫码登录")]
+ public IActionResult ScanLogin([FromBody] ScanDto dto)
+ {
+ if (dto == null) { return ToResponse(ResultCode.CUSTOM_ERROR, "扫码失败"); }
+
+ var token = HttpContextExtension.GetToken(HttpContext);
+ if (CacheService.GetScanLogin(dto.Uuid) is not null)
+ {
+ Dictionary dict = new() { };
+ dict.Add("status", "success");
+ dict.Add("token", token.Replace("Bearer ", ""));
+ CacheService.SetScanLogin(dto.Uuid, dict);
+ //TODO 待优化,应该生成新的token
+ return SUCCESS(1);
+ }
+ return ToResponse(ResultCode.FAIL, "二维码已失效");
+ }
+ #endregion
}
}
diff --git a/ZR.Admin.WebApi/Filters/GlobalActionMonitor.cs b/ZR.Admin.WebApi/Filters/GlobalActionMonitor.cs
index a4c00fa..1f11e79 100644
--- a/ZR.Admin.WebApi/Filters/GlobalActionMonitor.cs
+++ b/ZR.Admin.WebApi/Filters/GlobalActionMonitor.cs
@@ -1,12 +1,9 @@
-using Infrastructure;
-using Infrastructure.Attribute;
-using Infrastructure.Model;
+using Infrastructure.Extensions;
using IPTools.Core;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using NLog;
-using ZR.Admin.WebApi.Extensions;
using ZR.Model.System;
using ZR.Service.System.IService;
@@ -104,9 +101,9 @@ namespace ZR.Admin.WebApi.Filters
OperLocation = ip_info.Province + " " + ip_info.City,
Method = controller + "." + action + "()",
//Elapsed = _stopwatch.ElapsedMilliseconds,
- OperTime = DateTime.Now
+ OperTime = DateTime.Now,
+ OperParam = HttpContextExtension.GetRequestValue(context.HttpContext, method)
};
- HttpContextExtension.GetRequestValue(context.HttpContext, sysOperLog);
if (logAttribute != null)
{
@@ -117,7 +114,7 @@ namespace ZR.Admin.WebApi.Filters
}
LogEventInfo ei = new(NLog.LogLevel.Info, "GlobalActionMonitor", "");
-
+
ei.Properties["jsonResult"] = !HttpMethods.IsGet(method) ? jsonResult : "";
ei.Properties["requestParam"] = sysOperLog.OperParam;
ei.Properties["user"] = userName;
diff --git a/ZR.Admin.WebApi/Filters/VerifyAttribute.cs b/ZR.Admin.WebApi/Filters/VerifyAttribute.cs
index a925b3e..5e54c93 100644
--- a/ZR.Admin.WebApi/Filters/VerifyAttribute.cs
+++ b/ZR.Admin.WebApi/Filters/VerifyAttribute.cs
@@ -1,13 +1,7 @@
-using Infrastructure;
-using Infrastructure.Model;
-using Microsoft.AspNetCore.Authorization;
-using Microsoft.AspNetCore.Mvc;
+using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using NLog;
-using System;
-using System.Linq;
-using ZR.Admin.WebApi.Extensions;
using ZR.Admin.WebApi.Framework;
using ZR.Model.System.Dto;
diff --git a/ZR.Admin.WebApi/GlobalUsing.cs b/ZR.Admin.WebApi/GlobalUsing.cs
index 4d4888f..37d1b22 100644
--- a/ZR.Admin.WebApi/GlobalUsing.cs
+++ b/ZR.Admin.WebApi/GlobalUsing.cs
@@ -4,4 +4,5 @@ global using Infrastructure;
global using Infrastructure.Attribute;
global using Infrastructure.Enums;
global using Infrastructure.Model;
-global using Mapster;
\ No newline at end of file
+global using Mapster;
+global using Infrastructure.Extensions;
\ No newline at end of file
diff --git a/ZR.Admin.WebApi/Middleware/GlobalExceptionMiddleware.cs b/ZR.Admin.WebApi/Middleware/GlobalExceptionMiddleware.cs
index 3ee7baa..7668a2e 100644
--- a/ZR.Admin.WebApi/Middleware/GlobalExceptionMiddleware.cs
+++ b/ZR.Admin.WebApi/Middleware/GlobalExceptionMiddleware.cs
@@ -1,14 +1,8 @@
-using Infrastructure;
-using Infrastructure.Attribute;
-using Infrastructure.Model;
-using IPTools.Core;
+using IPTools.Core;
using Microsoft.AspNetCore.Http.Features;
using NLog;
-using System.Diagnostics;
using System.Text.Encodings.Web;
using System.Text.Json;
-using ZR.Admin.WebApi.Extensions;
-using ZR.Common;
using ZR.Model.System;
using ZR.Service.System.IService;
@@ -90,9 +84,9 @@ namespace ZR.Admin.WebApi.Middleware
ErrorMsg = string.IsNullOrEmpty(error) ? msg : error,
OperName = HttpContextExtension.GetName(context),
OperLocation = ip_info.Province + " " + ip_info.City,
- OperTime = DateTime.Now
+ OperTime = DateTime.Now,
+ OperParam = HttpContextExtension.GetRequestValue(context, context.Request.Method)
};
- HttpContextExtension.GetRequestValue(context, sysOperLog);
var endpoint = GetEndpoint(context);
if (endpoint != null)
{
diff --git a/ZR.Admin.WebApi/ZR.Admin.WebApi.csproj b/ZR.Admin.WebApi/ZR.Admin.WebApi.csproj
index 3acc417..7e82c93 100644
--- a/ZR.Admin.WebApi/ZR.Admin.WebApi.csproj
+++ b/ZR.Admin.WebApi/ZR.Admin.WebApi.csproj
@@ -20,7 +20,6 @@
-
diff --git a/ZR.Admin.WebApi/appsettings.json b/ZR.Admin.WebApi/appsettings.json
index 7161d38..9a3cf89 100644
--- a/ZR.Admin.WebApi/appsettings.json
+++ b/ZR.Admin.WebApi/appsettings.json
@@ -109,7 +109,7 @@
"RealIpHeader": "X-Real-IP",
"ClientIdHeader": "X-ClientId",
"HttpStatusCode": 429,
- "EndpointWhitelist": [ "post:/system/dict/data/types", "*:/msghub/negotiate", "*:/LogOut", "*:/common/uploadfile" ],
+ "EndpointWhitelist": [ "post:/system/dict/data/types", "*:/msghub/negotiate", "*:/LogOut", "*:/common/uploadfile", "*:/VerifyScan" ],
"QuotaExceededResponse": {
"Content": "{{\"code\":429,\"msg\":\"访问过于频繁,请稍后重试\"}}",
"ContentType": "application/json",
diff --git a/ZR.Model/System/Dto/LoginUser.cs b/ZR.Model/System/Dto/LoginUser.cs
index 8bf08d7..c06f742 100644
--- a/ZR.Model/System/Dto/LoginUser.cs
+++ b/ZR.Model/System/Dto/LoginUser.cs
@@ -1,5 +1,4 @@
-using System.Collections.Generic;
-using System.Linq;
+using System.Linq;
namespace ZR.Model.System.Dto
{
diff --git a/ZR.Model/System/Dto/ScanDto.cs b/ZR.Model/System/Dto/ScanDto.cs
new file mode 100644
index 0000000..063108e
--- /dev/null
+++ b/ZR.Model/System/Dto/ScanDto.cs
@@ -0,0 +1,9 @@
+namespace ZR.Model.System.Dto
+{
+ public class ScanDto
+ {
+ public string Uuid { get; set; }
+ public string State { get; set; }
+ public string DeviceId { get; set; }
+ }
+}
diff --git a/ZR.Service/System/CacheService.cs b/ZR.Service/System/CacheService.cs
index 1b5a336..7ba1ead 100644
--- a/ZR.Service/System/CacheService.cs
+++ b/ZR.Service/System/CacheService.cs
@@ -1,12 +1,11 @@
-using System.Collections.Generic;
-using System.Linq;
+using System;
using ZR.Common;
-using ZR.Common.Cache;
namespace ZR.Service.System
{
public class CacheService
{
+ private readonly static string CK_verifyScan = "verifyScan_";
#region 用户权限 缓存
public static List GetUserPerms(string key)
{
@@ -25,5 +24,40 @@ namespace ZR.Service.System
//RedisServer.Cache.Del(key);
}
#endregion
+
+ public static object SetScanLogin(string key, Dictionary val)
+ {
+ var ck = CK_verifyScan + key;
+
+ return CacheHelper.SetCache(ck,val , 1);
+ }
+ public static object GetScanLogin(string key)
+ {
+ var ck = CK_verifyScan + key;
+ return CacheHelper.Get(ck);
+ }
+ public static void RemoveScanLogin(string key)
+ {
+ var ck = CK_verifyScan + key;
+ CacheHelper.Remove(ck);
+ }
+
+ public static void SetLockUser(string key, long val, int time)
+ {
+ var CK = "lock_user_" + key;
+
+ CacheHelper.SetCache(CK, val, time);
+ }
+
+ public static long GetLockUser(string key)
+ {
+ var CK = "lock_user_" + key;
+
+ if (CacheHelper.Get(CK) is long t)
+ {
+ return t;
+ }
+ return 0;
+ }
}
}