diff --git a/Bootstrap.Admin/Controllers/AccountController.cs b/Bootstrap.Admin/Controllers/AccountController.cs index 56433c25..c5fa9ed1 100644 --- a/Bootstrap.Admin/Controllers/AccountController.cs +++ b/Bootstrap.Admin/Controllers/AccountController.cs @@ -2,9 +2,11 @@ using Bootstrap.DataAccess; using Longbow; using Longbow.Configuration; +using Longbow.Web; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using System; using System.Linq; @@ -34,13 +36,14 @@ namespace Bootstrap.Admin.Controllers /// Login the specified userName, password and remember. /// /// The login. + /// /// User name. /// Password. /// Remember. [HttpPost] - public async Task Login(string userName, string password, string remember) + public async Task Login([FromServices]IOnlineUsers onlineUserSvr, string userName, string password, string remember) { - if (UserHelper.Authenticate(userName, password)) + if (UserHelper.Authenticate(userName, password, loginUser => CreateLoginUser(onlineUserSvr, HttpContext, loginUser))) { var identity = new ClaimsIdentity(CookieAuthenticationDefaults.AuthenticationScheme); identity.AddClaim(new Claim(ClaimTypes.Name, userName)); @@ -51,6 +54,21 @@ namespace Bootstrap.Admin.Controllers return Redirect(originUrl); } + /// + /// + /// + /// + /// + /// + internal static void CreateLoginUser(IOnlineUsers onlineUserSvr, HttpContext context, LoginUser loginUser) + { + var agent = new UserAgent(context.Request.Headers["User-Agent"]); + loginUser.Ip = context.Connection.RemoteIpAddress?.ToString(); + loginUser.City = onlineUserSvr.RetrieveLocaleByIp(loginUser.Ip); + loginUser.Browser = $"{agent.Browser.Name} {agent.Browser.Version}"; + loginUser.OS = $"{agent.OS.Name} {agent.OS.Version}"; + } + /// /// Logout this instance. /// diff --git a/Bootstrap.Admin/Controllers/Api/LoginController.cs b/Bootstrap.Admin/Controllers/Api/LoginController.cs index ad81582f..425a276b 100644 --- a/Bootstrap.Admin/Controllers/Api/LoginController.cs +++ b/Bootstrap.Admin/Controllers/Api/LoginController.cs @@ -19,17 +19,18 @@ namespace Bootstrap.Admin.Controllers.Api /// /// /// + /// /// /// [AllowAnonymous] [HttpPost] - public string Post([FromBody]JObject value) + public string Post([FromServices]IOnlineUsers onlineUserSvr, [FromBody]JObject value) { string token = null; dynamic user = value; string userName = user.userName; string password = user.password; - if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(password) && UserHelper.Authenticate(userName, password)) + if (!string.IsNullOrEmpty(userName) && !string.IsNullOrEmpty(password) && UserHelper.Authenticate(userName, password, loginUser => AccountController.CreateLoginUser(onlineUserSvr, HttpContext, loginUser))) { token = BootstrapAdminJwtTokenHandler.CreateToken(userName); } diff --git a/Bootstrap.DataAccess/Helper/LoginHelper.cs b/Bootstrap.DataAccess/Helper/LoginHelper.cs new file mode 100644 index 00000000..31b9e057 --- /dev/null +++ b/Bootstrap.DataAccess/Helper/LoginHelper.cs @@ -0,0 +1,17 @@ +using Longbow.Data; + +namespace Bootstrap.DataAccess +{ + /// + /// + /// + public static class LoginHelper + { + /// + /// + /// + /// + /// + public static bool Log(LoginUser user) => DbContextManager.Create().Log(user); + } +} diff --git a/Bootstrap.DataAccess/Helper/UserHelper.cs b/Bootstrap.DataAccess/Helper/UserHelper.cs index eaf761e3..e92f5607 100644 --- a/Bootstrap.DataAccess/Helper/UserHelper.cs +++ b/Bootstrap.DataAccess/Helper/UserHelper.cs @@ -1,6 +1,7 @@ using Bootstrap.Security; using Longbow.Cache; using Longbow.Data; +using System; using System.Collections.Generic; namespace Bootstrap.DataAccess @@ -29,7 +30,21 @@ namespace Bootstrap.DataAccess /// /// /// - public static bool Authenticate(string userName, string password) => DbContextManager.Create().Authenticate(userName, password); + public static bool Authenticate(string userName, string password, Action config) + { + var loginUser = new LoginUser() + { + UserName = userName, + LoginTime = DateTime.Now, + Result = "登录失败" + }; + config(loginUser); + if (string.IsNullOrEmpty(loginUser.Ip)) loginUser.Ip = System.Net.IPAddress.IPv6Loopback.ToString(); + var ret = DbContextManager.Create().Authenticate(userName, password); + if (ret) loginUser.Result = "登录成功"; + LoginHelper.Log(loginUser); + return ret; + } /// /// 查询所有的新注册用户 diff --git a/Bootstrap.DataAccess/LoginUser.cs b/Bootstrap.DataAccess/LoginUser.cs new file mode 100644 index 00000000..44f159a2 --- /dev/null +++ b/Bootstrap.DataAccess/LoginUser.cs @@ -0,0 +1,64 @@ +using PetaPoco; +using System; + +namespace Bootstrap.DataAccess +{ + /// + /// + /// + [TableName("LoginLogs")] + public class LoginUser + { + /// + /// + /// + public string Id { get; set; } + + /// + /// + /// + public string UserName { get; set; } + + /// + /// + /// + public DateTime LoginTime { get; set; } + + /// + /// + /// + public string Ip { get; set; } + + /// + /// + /// + public string Browser { get; set; } + + /// + /// + /// + public string OS { get; set; } + + /// + /// + /// + public string City { get; set; } + + /// + /// + /// + public string Result { get; set; } + + /// + /// + /// + /// + /// + public virtual bool Log(LoginUser user) + { + var db = DbManager.Create(); + db.Save(user); + return true; + } + } +} diff --git a/DatabaseScripts/Install.sql b/DatabaseScripts/Install.sql index d472fd1e..cab77854 100644 --- a/DatabaseScripts/Install.sql +++ b/DatabaseScripts/Install.sql @@ -473,4 +473,34 @@ EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'显示名称' GO EXEC sys.sp_addextendedproperty @name=N'MS_Description', @value=N'注册时间' , @level0type=N'SCHEMA',@level0name=N'dbo', @level1type=N'TABLE',@level1name=N'RejectUsers', @level2type=N'COLUMN',@level2name=N'RegisterTime' -GO \ No newline at end of file +GO + +/****** Object: Table [dbo].[LoginLogs] Script Date: 03/03/2019 20:05:42 ******/ +SET ANSI_NULLS ON +GO + +SET QUOTED_IDENTIFIER ON +GO + +SET ANSI_PADDING ON +GO + +CREATE TABLE [dbo].[LoginLogs]( + [ID] [int] IDENTITY(1,1) NOT NULL, + [UserName] [varchar](50) NOT NULL, + [LoginTime] [datetime] NOT NULL, + [Ip] [varchar](15) NOT NULL, + [OS] [varchar](50) NULL, + [Browser] [varchar](50) NULL, + [City] [nvarchar](50) NULL, + [Result] [nvarchar](50) NOT NULL, + CONSTRAINT [PK_LoginLogs] PRIMARY KEY CLUSTERED +( + [ID] ASC +)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY] +) ON [PRIMARY] + +GO + +SET ANSI_PADDING OFF +GO