diff --git a/FAuth/Controllers/api/AccountController.cs b/FAuth/Controllers/api/AccountController.cs deleted file mode 100644 index 84c6cba..0000000 --- a/FAuth/Controllers/api/AccountController.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; -using Microsoft.Extensions.Logging; - -namespace FAuth.Controllers.api -{ - public class AccountController:ApiControllerBase - { - public AccountController(ILogger logger,IServiceProvider service) : base(logger,service) { - } - } -} diff --git a/FAuth/Controllers/api/ApiControllerBase.cs b/FAuth/Controllers/api/ApiControllerBase.cs index 9f84798..9f99289 100644 --- a/FAuth/Controllers/api/ApiControllerBase.cs +++ b/FAuth/Controllers/api/ApiControllerBase.cs @@ -1,4 +1,5 @@ using System; +using FAuth.Models; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; @@ -8,6 +9,8 @@ namespace FAuth.Controllers.api /// api控制器基类 /// [ApiController, Route("api/[Controller]/[Action]")] + [ServiceFilter(typeof(ApiExceptionFilterAttribute))] + [ProducesResponseType(typeof(ApiErrorResult),500)] public abstract class ApiControllerBase:ControllerBase { public ApiControllerBase(ILogger logger,IServiceProvider service) : base(logger,service) { diff --git a/FAuth/Controllers/api/UserController.cs b/FAuth/Controllers/api/UserController.cs index c9ce7cb..cd854b4 100644 --- a/FAuth/Controllers/api/UserController.cs +++ b/FAuth/Controllers/api/UserController.cs @@ -8,6 +8,9 @@ using Microsoft.Extensions.Logging; using FAuth.DataBase.Tables; using Microsoft.AspNetCore.Mvc.ModelBinding; using FAuth.Extensions.Decryptor; +using FAuth.DataBase; +using Microsoft.EntityFrameworkCore; +using Falcon.Extend; namespace FAuth.Controllers.api { @@ -17,8 +20,13 @@ namespace FAuth.Controllers.api public class UserController:ApiControllerBase { public IUserTicketDryptor UserTicketDryptor { get; set; } + public FAuthDb Db { get; set; } - public UserController(ILogger logger,IServiceProvider service,IUserTicketDryptor userTicketDryptor) + public UserController( + ILogger logger, + IServiceProvider service, + IUserTicketDryptor userTicketDryptor, + FAuthDb db) : base(logger,service) { if(logger is null) @@ -26,6 +34,7 @@ namespace FAuth.Controllers.api if(service is null) throw new ArgumentNullException(nameof(service)); this.UserTicketDryptor = userTicketDryptor ?? throw new ArgumentNullException(nameof(userTicketDryptor)); + this.Db = db ?? throw new ArgumentNullException(nameof(db)); } /// @@ -37,10 +46,20 @@ namespace FAuth.Controllers.api [HttpPost] [ProducesResponseType(typeof(CheckUserResult),200)] public CheckUserResult CheckUser(string userName,string password) { + if(userName.IsNullOrEmpty()) { + throw new ArgumentNullException(nameof(userName)); + } + var qu = this.Db.Users.Where(m => m.UserName == userName && m.Password == password); + if(!qu.Any()) { + throw new Exception("提供的用户名或密码不正确"); + } + var fir = qu.First(); + fir.LastLoginDatetime = DateTimeOffset.Now; + this.Db.SaveChangesAsync().Wait(); return new CheckUserResult { - Result = userName == password, Ticket = this.UserTicketDryptor.Encrypt(new UserTicketModel { - UserName = userName, + Id = fir.Id, + UserName = fir.UserName, }), }; } @@ -53,9 +72,20 @@ namespace FAuth.Controllers.api [HttpPost] [ProducesResponseType(typeof(UserInfo),200)] public UserInfo GetUserByTicket([BindRequired]string ticket) { - var userTicketModel = this.UserTicketDryptor.Decrypt(ticket); + if(ticket.IsNullOrEmpty()) { + throw new ArgumentNullException(nameof(ticket)); + } + UserTicketModel userTicketModel = null; + userTicketModel = this.UserTicketDryptor.Decrypt(ticket); + var qu = this.Db.Users.Where(m => m.Id == userTicketModel.Id); + if(!qu.Any()) { + throw new Exception("提交的票据信息错误"); + } + var fir = qu.First(); return new UserInfo { - UserName = userTicketModel.UserName, + Id = fir.Id, + LastLoginDatetime = fir.LastLoginDatetime, + UserName = fir.UserName, }; } @@ -67,6 +97,50 @@ namespace FAuth.Controllers.api /// 是否成功 [HttpPost] public bool ChangePassword(string ticket,string nPassword) { + if(ticket.IsNullOrEmpty()) { + throw new ArgumentNullException(nameof(ticket)); + } + var userTicketModel = this.UserTicketDryptor.Decrypt(ticket); + var qu = this.Db.Users.Where(m => m.Id == userTicketModel.Id); + if(!qu.Any()) { + throw new Exception("没找到票据对应用户"); + } + foreach(var item in qu) { + item.Password = nPassword; + } + this.Db.SaveChangesAsync().Wait(); + return true; + } + + /// + /// 通过提供管理员票据和新用户信息创建用户 + /// + /// 管理员票据 + /// 登录用户名 + /// 用户名称 + /// 用户密码 + /// 是否成功 + [HttpPost] + public bool AddNewUser(string adminTicket,string userName,string name,string password) { + if(string.IsNullOrEmpty(adminTicket)) + throw new ArgumentException("必须提供管理票据",nameof(adminTicket)); + if(string.IsNullOrEmpty(userName)) + throw new ArgumentException("新用户登录名不能为空",nameof(userName)); + if(string.IsNullOrEmpty(name)) + throw new ArgumentException("用户姓名不能为空",nameof(name)); + if(string.IsNullOrEmpty(password)) + throw new ArgumentException("密码不能为空",nameof(password)); + var qu = this.Db.Users.Where(m => m.UserName == userName); + if(qu.Any()) { + throw new Exception("用户登录名已经存在,不能重复添加"); + } + var nUser = new FUser { + Name = name, + UserName = userName, + Password = password, + }; + this.Db.Entry(nUser).State = EntityState.Added; + this.Db.SaveChangesAsync().Wait(); return true; } } diff --git a/FAuth/DataBase/FAuthDb.cs b/FAuth/DataBase/FAuthDb.cs index 3f41f00..2b08e79 100644 --- a/FAuth/DataBase/FAuthDb.cs +++ b/FAuth/DataBase/FAuthDb.cs @@ -1,7 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Threading.Tasks; +using FAuth.DataBase.Tables; using Microsoft.EntityFrameworkCore; namespace FAuth.DataBase @@ -11,5 +8,12 @@ namespace FAuth.DataBase /// public class FAuthDb:DbContext { + public FAuthDb(DbContextOptions options) : base(options) { + Database.EnsureCreatedAsync().Wait(); + } + /// + /// 用户表 + /// + public DbSet Users { get; set; } } } diff --git a/FAuth/DataBase/Tables/FUser.cs b/FAuth/DataBase/Tables/FUser.cs index 13cc3b1..d30e12b 100644 --- a/FAuth/DataBase/Tables/FUser.cs +++ b/FAuth/DataBase/Tables/FUser.cs @@ -1,4 +1,5 @@ using System; +using System.ComponentModel.DataAnnotations; namespace FAuth.DataBase.Tables { @@ -10,18 +11,26 @@ namespace FAuth.DataBase.Tables /// /// 用户流水编号 /// + [Key] public int Id { get; set; } /// - /// 用户安全编号 - /// - public Guid SId { get; set; } - /// /// 用户登录名 /// + [Required, MaxLength(20)] public string UserName { get; set; } /// + /// 用户姓名 + /// + [Required, MaxLength(20)] + public string Name { get; set; } + /// /// 登录密码 /// + [Required, MaxLength(20)] public string Password { get; set; } + /// + /// 上次登录时间 + /// + public DateTimeOffset? LastLoginDatetime { get; set; } } } diff --git a/FAuth/Extensions/Decryptor/UserTicketModel.cs b/FAuth/Extensions/Decryptor/UserTicketModel.cs index 99b8803..66507f2 100644 --- a/FAuth/Extensions/Decryptor/UserTicketModel.cs +++ b/FAuth/Extensions/Decryptor/UserTicketModel.cs @@ -5,6 +5,10 @@ /// public class UserTicketModel { + /// + /// 用户编号 + /// + public int Id { get; set; } /// /// 登录用户名称 /// diff --git a/FAuth/Models/ApiErrorResult.cs b/FAuth/Models/ApiErrorResult.cs new file mode 100644 index 0000000..2b22a3f --- /dev/null +++ b/FAuth/Models/ApiErrorResult.cs @@ -0,0 +1,17 @@ +namespace FAuth.Models +{ + /// + /// api返回异常 + /// + public class ApiErrorResult + { + /// + /// 异常信心 + /// + public string Message { get; set; } + /// + /// 客户端存储编号 + /// + public string Storage { get; set; } + } +} diff --git a/FAuth/Models/ApiExceptionFilterAttribute.cs b/FAuth/Models/ApiExceptionFilterAttribute.cs new file mode 100644 index 0000000..5cc3845 --- /dev/null +++ b/FAuth/Models/ApiExceptionFilterAttribute.cs @@ -0,0 +1,31 @@ +using System; +using Microsoft.AspNetCore.Http; +using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Mvc.Filters; +using Microsoft.Extensions.Logging; + +namespace FAuth.Models +{ + /// + /// Api控制器返回异常 + /// + [AttributeUsage(AttributeTargets.Class | AttributeTargets.Method,AllowMultiple = true,Inherited = true)] + public class ApiExceptionFilterAttribute:ExceptionFilterAttribute + { + public ILogger Logger { get; set; } + + public ApiExceptionFilterAttribute(ILogger logger) { + this.Logger = logger; + } + public override void OnException(ExceptionContext context) { + this.Logger.LogError(context.Exception.ToString()); + var storage = Guid.NewGuid().ToString(); + var result = new ApiErrorResult { + Message = context.Exception.Message, + Storage = storage, + }; + context.Result = new JsonResult(result) { StatusCode = StatusCodes.Status500InternalServerError }; + } + + } +} diff --git a/FAuth/Models/CheckUserResult.cs b/FAuth/Models/CheckUserResult.cs index 8972447..895eaad 100644 --- a/FAuth/Models/CheckUserResult.cs +++ b/FAuth/Models/CheckUserResult.cs @@ -10,10 +10,6 @@ namespace FAuth.Models /// public class CheckUserResult { - /// - /// 验证结果 - /// - public bool Result { get; set; } /// /// 票据 /// diff --git a/FAuth/Models/UserInfo.cs b/FAuth/Models/UserInfo.cs index d57a721..96fd4f0 100644 --- a/FAuth/Models/UserInfo.cs +++ b/FAuth/Models/UserInfo.cs @@ -10,10 +10,17 @@ namespace FAuth.Models /// public class UserInfo { + /// + /// 用户编号 + /// + public int Id { get; set; } /// /// 用户登录名 /// public string UserName { get; set; } - + /// + /// 上次登录时间 + /// + public DateTimeOffset? LastLoginDatetime { get; set; } } } diff --git a/FAuth/Startup.cs b/FAuth/Startup.cs index f116608..fd1092e 100644 --- a/FAuth/Startup.cs +++ b/FAuth/Startup.cs @@ -5,8 +5,10 @@ using System.Text.Unicode; using Falcon.Extend; using FAuth.DataBase; using FAuth.Extensions.Decryptor; +using FAuth.Models; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Hosting; +using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Caching.Redis; using Microsoft.Extensions.Configuration; using Microsoft.Extensions.DependencyInjection; @@ -34,7 +36,9 @@ namespace FAuth //עJsonл services.AddMsJsonProvider(); //עݿ - services.AddDbContext(); + services.AddDbContext(option => { + option.UseSqlServer(Configuration.GetConnectionString("FAuthDb")); + }); //עRedis var rop = this.Configuration.GetSection("Redis").Get(); services.AddRedis(rop); @@ -64,6 +68,8 @@ namespace FAuth services.AddAESCrypto(); var UTDO = Configuration.GetSection("UserTicketDecryptorOption"); services.AddUserTicketDryptor(UTDO); + //עapi + services.AddScoped(); } // This method gets called by the runtime. Use this method to configure the HTTP request pipeline. @@ -83,7 +89,7 @@ namespace FAuth app.UseSwagger(); app.UseSwaggerUI(c => { c.SwaggerEndpoint("/swagger/V1/swagger.json","ӿĵ"); - c.RoutePrefix = "api"; + c.RoutePrefix = ""; }); app.UseAuthorization(); diff --git a/FAuth/appsettings.json b/FAuth/appsettings.json index c3e5610..2d150af 100644 --- a/FAuth/appsettings.json +++ b/FAuth/appsettings.json @@ -7,8 +7,8 @@ } }, "AllowedHosts": "*", - "ConnectionString": { - "MzbkDb": "Server=.\\SQLSERVER2008R2;Database=mzbk;User ID=sa;Password=111" + "ConnectionStrings": { + "FAuthDb": "Server=.\\SQLSERVER2008R2;Database=FAuth;User ID=sa;Password=111" }, "Redis": { "InstanceName": "",