接口响应错误处理。数据库实现等

This commit is contained in:
falcon 2020-04-10 18:15:11 +08:00
parent 4e55b1938d
commit 7ee12e8bf7
12 changed files with 173 additions and 36 deletions

View File

@ -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<AccountController>
{
public AccountController(ILogger<AccountController> logger,IServiceProvider service) : base(logger,service) {
}
}
}

View File

@ -1,4 +1,5 @@
using System; using System;
using FAuth.Models;
using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging;
@ -8,6 +9,8 @@ namespace FAuth.Controllers.api
/// api控制器基类 /// api控制器基类
/// </summary> /// </summary>
[ApiController, Route("api/[Controller]/[Action]")] [ApiController, Route("api/[Controller]/[Action]")]
[ServiceFilter(typeof(ApiExceptionFilterAttribute))]
[ProducesResponseType(typeof(ApiErrorResult),500)]
public abstract class ApiControllerBase<LoggerType>:ControllerBase<LoggerType> public abstract class ApiControllerBase<LoggerType>:ControllerBase<LoggerType>
{ {
public ApiControllerBase(ILogger<LoggerType> logger,IServiceProvider service) : base(logger,service) { public ApiControllerBase(ILogger<LoggerType> logger,IServiceProvider service) : base(logger,service) {

View File

@ -8,6 +8,9 @@ using Microsoft.Extensions.Logging;
using FAuth.DataBase.Tables; using FAuth.DataBase.Tables;
using Microsoft.AspNetCore.Mvc.ModelBinding; using Microsoft.AspNetCore.Mvc.ModelBinding;
using FAuth.Extensions.Decryptor; using FAuth.Extensions.Decryptor;
using FAuth.DataBase;
using Microsoft.EntityFrameworkCore;
using Falcon.Extend;
namespace FAuth.Controllers.api namespace FAuth.Controllers.api
{ {
@ -17,8 +20,13 @@ namespace FAuth.Controllers.api
public class UserController:ApiControllerBase<UserController> public class UserController:ApiControllerBase<UserController>
{ {
public IUserTicketDryptor UserTicketDryptor { get; set; } public IUserTicketDryptor UserTicketDryptor { get; set; }
public FAuthDb Db { get; set; }
public UserController(ILogger<UserController> logger,IServiceProvider service,IUserTicketDryptor userTicketDryptor) public UserController(
ILogger<UserController> logger,
IServiceProvider service,
IUserTicketDryptor userTicketDryptor,
FAuthDb db)
: base(logger,service) { : base(logger,service) {
if(logger is null) if(logger is null)
@ -26,6 +34,7 @@ namespace FAuth.Controllers.api
if(service is null) if(service is null)
throw new ArgumentNullException(nameof(service)); throw new ArgumentNullException(nameof(service));
this.UserTicketDryptor = userTicketDryptor ?? throw new ArgumentNullException(nameof(userTicketDryptor)); this.UserTicketDryptor = userTicketDryptor ?? throw new ArgumentNullException(nameof(userTicketDryptor));
this.Db = db ?? throw new ArgumentNullException(nameof(db));
} }
/// <summary> /// <summary>
@ -37,10 +46,20 @@ namespace FAuth.Controllers.api
[HttpPost] [HttpPost]
[ProducesResponseType(typeof(CheckUserResult),200)] [ProducesResponseType(typeof(CheckUserResult),200)]
public CheckUserResult CheckUser(string userName,string password) { 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 { return new CheckUserResult {
Result = userName == password,
Ticket = this.UserTicketDryptor.Encrypt(new UserTicketModel { Ticket = this.UserTicketDryptor.Encrypt(new UserTicketModel {
UserName = userName, Id = fir.Id,
UserName = fir.UserName,
}), }),
}; };
} }
@ -53,9 +72,20 @@ namespace FAuth.Controllers.api
[HttpPost] [HttpPost]
[ProducesResponseType(typeof(UserInfo),200)] [ProducesResponseType(typeof(UserInfo),200)]
public UserInfo GetUserByTicket([BindRequired]string ticket) { 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 { return new UserInfo {
UserName = userTicketModel.UserName, Id = fir.Id,
LastLoginDatetime = fir.LastLoginDatetime,
UserName = fir.UserName,
}; };
} }
@ -67,6 +97,50 @@ namespace FAuth.Controllers.api
/// <returns>是否成功</returns> /// <returns>是否成功</returns>
[HttpPost] [HttpPost]
public bool ChangePassword(string ticket,string nPassword) { 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;
}
/// <summary>
/// 通过提供管理员票据和新用户信息创建用户
/// </summary>
/// <param name="adminTicket">管理员票据</param>
/// <param name="userName">登录用户名</param>
/// <param name="name">用户名称</param>
/// <param name="password">用户密码</param>
/// <returns>是否成功</returns>
[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; return true;
} }
} }

View File

@ -1,7 +1,4 @@
using System; using FAuth.DataBase.Tables;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore; using Microsoft.EntityFrameworkCore;
namespace FAuth.DataBase namespace FAuth.DataBase
@ -11,5 +8,12 @@ namespace FAuth.DataBase
/// </summary> /// </summary>
public class FAuthDb:DbContext public class FAuthDb:DbContext
{ {
public FAuthDb(DbContextOptions options) : base(options) {
Database.EnsureCreatedAsync().Wait();
}
/// <summary>
/// 用户表
/// </summary>
public DbSet<FUser> Users { get; set; }
} }
} }

View File

@ -1,4 +1,5 @@
using System; using System;
using System.ComponentModel.DataAnnotations;
namespace FAuth.DataBase.Tables namespace FAuth.DataBase.Tables
{ {
@ -10,18 +11,26 @@ namespace FAuth.DataBase.Tables
/// <summary> /// <summary>
/// 用户流水编号 /// 用户流水编号
/// </summary> /// </summary>
[Key]
public int Id { get; set; } public int Id { get; set; }
/// <summary> /// <summary>
/// 用户安全编号
/// </summary>
public Guid SId { get; set; }
/// <summary>
/// 用户登录名 /// 用户登录名
/// </summary> /// </summary>
[Required, MaxLength(20)]
public string UserName { get; set; } public string UserName { get; set; }
/// <summary> /// <summary>
/// 用户姓名
/// </summary>
[Required, MaxLength(20)]
public string Name { get; set; }
/// <summary>
/// 登录密码 /// 登录密码
/// </summary> /// </summary>
[Required, MaxLength(20)]
public string Password { get; set; } public string Password { get; set; }
/// <summary>
/// 上次登录时间
/// </summary>
public DateTimeOffset? LastLoginDatetime { get; set; }
} }
} }

View File

@ -5,6 +5,10 @@
/// </summary> /// </summary>
public class UserTicketModel public class UserTicketModel
{ {
/// <summary>
/// 用户编号
/// </summary>
public int Id { get; set; }
/// <summary> /// <summary>
/// 登录用户名称 /// 登录用户名称
/// </summary> /// </summary>

View File

@ -0,0 +1,17 @@
namespace FAuth.Models
{
/// <summary>
/// api返回异常
/// </summary>
public class ApiErrorResult
{
/// <summary>
/// 异常信心
/// </summary>
public string Message { get; set; }
/// <summary>
/// 客户端存储编号
/// </summary>
public string Storage { get; set; }
}
}

View File

@ -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
{
/// <summary>
/// Api控制器返回异常
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method,AllowMultiple = true,Inherited = true)]
public class ApiExceptionFilterAttribute:ExceptionFilterAttribute
{
public ILogger Logger { get; set; }
public ApiExceptionFilterAttribute(ILogger<ApiExceptionFilterAttribute> 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 };
}
}
}

View File

@ -10,10 +10,6 @@ namespace FAuth.Models
/// </summary> /// </summary>
public class CheckUserResult public class CheckUserResult
{ {
/// <summary>
/// 验证结果
/// </summary>
public bool Result { get; set; }
/// <summary> /// <summary>
/// 票据 /// 票据
/// </summary> /// </summary>

View File

@ -10,10 +10,17 @@ namespace FAuth.Models
/// </summary> /// </summary>
public class UserInfo public class UserInfo
{ {
/// <summary>
/// 用户编号
/// </summary>
public int Id { get; set; }
/// <summary> /// <summary>
/// 用户登录名 /// 用户登录名
/// </summary> /// </summary>
public string UserName { get; set; } public string UserName { get; set; }
/// <summary>
/// 上次登录时间
/// </summary>
public DateTimeOffset? LastLoginDatetime { get; set; }
} }
} }

View File

@ -5,8 +5,10 @@ using System.Text.Unicode;
using Falcon.Extend; using Falcon.Extend;
using FAuth.DataBase; using FAuth.DataBase;
using FAuth.Extensions.Decryptor; using FAuth.Extensions.Decryptor;
using FAuth.Models;
using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting; using Microsoft.AspNetCore.Hosting;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Caching.Redis; using Microsoft.Extensions.Caching.Redis;
using Microsoft.Extensions.Configuration; using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.DependencyInjection;
@ -34,7 +36,9 @@ namespace FAuth
//注册Json序列化 //注册Json序列化
services.AddMsJsonProvider(); services.AddMsJsonProvider();
//注册数据库 //注册数据库
services.AddDbContext<FAuthDb>(); services.AddDbContext<FAuthDb>(option => {
option.UseSqlServer(Configuration.GetConnectionString("FAuthDb"));
});
//注册Redis //注册Redis
var rop = this.Configuration.GetSection("Redis").Get<RedisCacheOptions>(); var rop = this.Configuration.GetSection("Redis").Get<RedisCacheOptions>();
services.AddRedis(rop); services.AddRedis(rop);
@ -64,6 +68,8 @@ namespace FAuth
services.AddAESCrypto(); services.AddAESCrypto();
var UTDO = Configuration.GetSection("UserTicketDecryptorOption"); var UTDO = Configuration.GetSection("UserTicketDecryptorOption");
services.AddUserTicketDryptor(UTDO); services.AddUserTicketDryptor(UTDO);
//注册api错误处理器
services.AddScoped<ApiExceptionFilterAttribute>();
} }
// This method gets called by the runtime. Use this method to configure the HTTP request pipeline. // 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.UseSwagger();
app.UseSwaggerUI(c => { app.UseSwaggerUI(c => {
c.SwaggerEndpoint("/swagger/V1/swagger.json","接口文档"); c.SwaggerEndpoint("/swagger/V1/swagger.json","接口文档");
c.RoutePrefix = "api"; c.RoutePrefix = "";
}); });
app.UseAuthorization(); app.UseAuthorization();

View File

@ -7,8 +7,8 @@
} }
}, },
"AllowedHosts": "*", "AllowedHosts": "*",
"ConnectionString": { "ConnectionStrings": {
"MzbkDb": "Server=.\\SQLSERVER2008R2;Database=mzbk;User ID=sa;Password=111" "FAuthDb": "Server=.\\SQLSERVER2008R2;Database=FAuth;User ID=sa;Password=111"
}, },
"Redis": { "Redis": {
"InstanceName": "", "InstanceName": "",