update:请求加密&防篡改

This commit is contained in:
2021-02-25 10:39:30 +08:00
parent 9834c7a988
commit 7fe75e8c7c
11 changed files with 145 additions and 27 deletions

View File

@@ -0,0 +1,32 @@
using Dapper;
using Microsoft.Extensions.Configuration;
using MySqlConnector;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace QRCodeService.Application.Queries
{
public class AppQueries : IAppQueries
{
readonly string _connectionString;
public AppQueries(IConfiguration configuration)
{
_connectionString = configuration.GetConnectionString("default");
}
public async Task<App> GetAppAsync(int id)
{
using (var connection = new MySqlConnection(_connectionString))
{
connection.Open();
var app = await connection.QueryAsync<App>(
@"SELECT Id,AppKey,Remarks FROM App WHERE Id = @id", new { id });
return app.SingleOrDefault();
}
}
}
}

View File

@@ -0,0 +1,15 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace QRCodeService.Application.Queries
{
public class App
{
public int Id { get; set; }
public string Appkey { get; set; }
public string Remarks { get; set; }
}
}

View File

@@ -6,8 +6,8 @@ using System.Threading.Tasks;
namespace QRCodeService.Application.Queries namespace QRCodeService.Application.Queries
{ {
public class GetLinkQueryHandler public interface IAppQueries
{ {
Task<App> GetAppAsync(int id);
} }
} }

View File

@@ -26,7 +26,7 @@ namespace QRCodeService.Application.Queries
connection.Open(); connection.Open();
var link = await connection.QueryAsync<Link>( var link = await connection.QueryAsync<Link>(
@"SELECT ShortCode,FullUrl FROM Link WHERE ShortCode = @shortCode",new {shortCode }); @"SELECT ShortCode,FullUrl FROM Link WHERE ShortCode = @shortCode",new {shortCode });
return link.Single(); return link.SingleOrDefault();
} }
} }
} }

View File

@@ -18,12 +18,14 @@ namespace QRCodeService.Controllers.Api
public class LinkController:ControllerBase public class LinkController:ControllerBase
{ {
readonly IMediator mediator; readonly IMediator mediator;
readonly ILinkQueries queries; readonly ILinkQueries linkQueries;
readonly IAppQueries appQueries;
public LinkController(IMediator mediator, ILinkQueries queries) public LinkController(IMediator mediator, ILinkQueries queries, IAppQueries appQueries)
{ {
this.mediator = mediator; this.mediator = mediator;
this.queries = queries; this.linkQueries = queries;
this.appQueries = appQueries;
} }
[HttpGet] [HttpGet]
@@ -34,6 +36,15 @@ namespace QRCodeService.Controllers.Api
[HttpPost] [HttpPost]
public async Task<IActionResult> Create(CreateLinkModel input) public async Task<IActionResult> Create(CreateLinkModel input)
{ {
var app = await appQueries.GetAppAsync(input.AppId);
if (app == null)
{
return BadRequest();
}
if (! await input.CheckValidAsync(app.Appkey))
{
return BadRequest();
}
var command = new CreateLinkCommand(input.SuffixUrl,1); var command = new CreateLinkCommand(input.SuffixUrl,1);
var link = await mediator.Send(command); var link = await mediator.Send(command);
if (link==null) if (link==null)

View File

@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Globalization;
using System.Linq; using System.Linq;
using System.Security.Cryptography; using System.Security.Cryptography;
using System.Text; using System.Text;
@@ -17,5 +18,30 @@ namespace QRCodeService.Extensions
return result; return result;
} }
} }
public static DateTime? ToDate(this string dateTimeStr, string[] dateFmt)
{
// example: var dt = "2011-03-21 13:26".toDate(new string[]{"yyyy-MM-dd HH:mm",
// "M/d/yyyy h:mm:ss tt"});
const DateTimeStyles style = DateTimeStyles.AllowWhiteSpaces;
if (dateFmt == null)
{
var dateInfo = System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat;
dateFmt = dateInfo.GetAllDateTimePatterns();
}
DateTime? result = null;
DateTime dt;
if (DateTime.TryParseExact(dateTimeStr, dateFmt,
CultureInfo.InvariantCulture, style, out dt)) result = dt;
return result;
}
public static DateTime? ToDate(this string dateTimeStr, string dateFmt = null)
{
// example: var dt="2011-03-21 13:26".toDate("yyyy-MM-dd HH:mm");
// or simply var dt="2011-03-21 13:26".toDate();
// call overloaded function with string array param
string[] dateFmtArr = dateFmt == null ? null : new string[] { dateFmt };
return ToDate(dateTimeStr, dateFmtArr);
}
} }
} }

View File

@@ -0,0 +1,43 @@
using QRCodeService.Application.Queries;
using QRCodeService.Extensions;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace QRCodeService.Models
{
public abstract class CheckSignModel
{
public int AppId { get; set; }
public string Time { get; set; }
public string Sign { get; set; }
public async Task<bool> CheckSignAsync(string appkey)
{
//除Sign字段以外按key名排序
var props = this.GetType().GetProperties();
var signStr = string.Join(null,props.Where(p=>p.Name!="Sign").OrderBy(p => p.Name).Select(p=>p.GetValue(this).ToString()));
var sign = Convert.ToBase64String((signStr + appkey).ToMD5());
return sign == Sign;
}
public bool CheckTime()
{
var timeDate = Time.ToDate("yyyyMMddhhmmss");
if (timeDate == null)
{
return false;
}
if (Math.Abs((timeDate.Value - DateTime.Now).TotalSeconds) > 60)
{
return false;
}
return true;
}
public async Task<bool> CheckValidAsync(string appkey)
{
return CheckTime() && await CheckSignAsync(appkey);
}
}
}

View File

@@ -1,4 +1,5 @@
using System; using QRCodeService.Application.Queries;
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Text; using System.Text;
@@ -6,9 +7,8 @@ using System.Threading.Tasks;
namespace QRCodeService.Models namespace QRCodeService.Models
{ {
public class CreateLinkModel public class CreateLinkModel: CheckSignModel
{ {
public string SuffixUrl { get; set; } public string SuffixUrl { get; set; }
public string Time { get; set; }
} }
} }

View File

@@ -1,16 +0,0 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace QRCodeService.Models
{
public class GenInputModel
{
public int AppId { get; set; }
public string Time { get; set; }
public string SuffixUrl { get; set; }
public string Sign { get; set; }
}
}

View File

@@ -71,8 +71,10 @@ namespace QRCodeService
//Repository //Repository
services.AddScoped<IAppRepository, AppRepository>(); services.AddScoped<IAppRepository, AppRepository>();
services.AddScoped<ILinkRepository, LinkRepository>(); services.AddScoped<ILinkRepository, LinkRepository>();
//Queries
services.AddScoped<ILinkQueries, LinkQueries>(); services.AddScoped<ILinkQueries, LinkQueries>();
services.AddScoped<IAppQueries, AppQueries>();
} }
// 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.

View File

@@ -1 +1,6 @@
# 施工图审查系统二维码短链生成服务 # 施工图审查系统二维码短链生成服务
## 开发环境搭建
1. 安装vs 2019
2. 安装.net 5 SDK
3. 安装docker desktop
## 启动项目