Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
c6b9746603 | ||
|
|
f7e1b9be2a | ||
|
|
d0fe883e74 | ||
|
|
e4773f3154 | ||
|
|
ba7b3ecd60 | ||
|
|
f52c19938f | ||
|
|
83ab8ba385 | ||
|
|
7d70e8326a | ||
|
|
2abe486151 | ||
|
|
f1138a5a10 | ||
|
|
31df4a7593 |
@@ -1,4 +1,4 @@
|
||||
name: CI
|
||||
name: PublishNugetPackage
|
||||
|
||||
on: [create]
|
||||
|
||||
@@ -29,6 +29,6 @@ jobs:
|
||||
run: |
|
||||
version=`git describe --tags`
|
||||
dotnet pack --configuration release -p:PackageVersion=$version
|
||||
dotnet nuget push bin/release/YY-Tech.YYApi.$version.nupkg -k ${APIKEY} -s https://www.nuget.org/api/v2/package
|
||||
dotnet nuget push bin/release/Simcu.SimApi.$version.nupkg -k ${NUGET_APIKEY} -s https://www.nuget.org/api/v2/package
|
||||
env:
|
||||
APIKEY: ${{ secrets.APPKEY }}
|
||||
NUGET_APIKEY: ${{ secrets.NUGET_APIKEY }}
|
||||
|
||||
@@ -1,49 +1,58 @@
|
||||
using System;
|
||||
using System.Linq;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using YYApi.Communications;
|
||||
using YYApi.Exceptions;
|
||||
using SimApi.Communications;
|
||||
using SimApi.Exceptions;
|
||||
|
||||
namespace YYApi.Attributes
|
||||
namespace SimApi.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// 检测登录中间件
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
|
||||
public class YYAuthAttribute : ActionFilterAttribute
|
||||
public class SimApiAuthAttribute : ActionFilterAttribute
|
||||
{
|
||||
private string[] Types { get; }
|
||||
|
||||
|
||||
//默认是user登录类型
|
||||
public YYAuthAttribute()
|
||||
public SimApiAuthAttribute()
|
||||
{
|
||||
Types = new[] { "user" };
|
||||
}
|
||||
|
||||
//只检测一种用户类型的快捷方式
|
||||
public YYAuthAttribute(string type)
|
||||
public SimApiAuthAttribute(string type)
|
||||
{
|
||||
Types = new[] { type };
|
||||
}
|
||||
|
||||
//设定特定类型的检测
|
||||
public YYAuthAttribute(string[] types)
|
||||
public SimApiAuthAttribute(string[] types)
|
||||
{
|
||||
Types = types;
|
||||
}
|
||||
|
||||
//只检测一种用户类型的快捷方式
|
||||
public SimApiAuthAttribute(string type, string url)
|
||||
{
|
||||
Types = new[] { type };
|
||||
new HttpPostAttribute(url);
|
||||
}
|
||||
|
||||
public override void OnActionExecuting(ActionExecutingContext context)
|
||||
{
|
||||
var loginInfo = (YYLoginItem)context.HttpContext.Items["LoginInfo"];
|
||||
var loginInfo = (SimApiLoginItem)context.HttpContext.Items["LoginInfo"];
|
||||
//检测是否登录
|
||||
if (loginInfo == null)
|
||||
{
|
||||
throw new YYApiException(401);
|
||||
throw new SimApiException(401);
|
||||
}
|
||||
//检测用户类型
|
||||
if (Types.Intersect(loginInfo.Type).Count() == 0)
|
||||
{
|
||||
throw new YYApiException(403);
|
||||
throw new SimApiException(403);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,20 +1,20 @@
|
||||
using System;
|
||||
using Swashbuckle.AspNetCore.Annotations;
|
||||
|
||||
namespace YYApi.Attributes
|
||||
namespace SimApi.Attributes
|
||||
{
|
||||
/// <summary>
|
||||
/// 快捷自定义接口文档类
|
||||
/// </summary>
|
||||
[AttributeUsage(AttributeTargets.Method | AttributeTargets.Class)]
|
||||
public class YYDocAttribute : SwaggerOperationAttribute
|
||||
public class SimApiDocAttribute : SwaggerOperationAttribute
|
||||
{
|
||||
/// <summary>
|
||||
/// 定义接口说明
|
||||
/// </summary>
|
||||
/// <param name="tag">接口分组</param>
|
||||
/// <param name="name">接口名称</param>
|
||||
public YYDocAttribute(string tag, string name)
|
||||
public SimApiDocAttribute(string tag, string name)
|
||||
{
|
||||
Tags = new[] { tag };
|
||||
Summary = name;
|
||||
@@ -1,10 +1,10 @@
|
||||
using System;
|
||||
namespace YYApi.Communications
|
||||
namespace SimApi.Communications
|
||||
{
|
||||
/// <summary>
|
||||
/// 只有ID的请求
|
||||
/// </summary>
|
||||
public class YYIdOnlyRequest
|
||||
public class SimApiIdOnlyRequest
|
||||
{
|
||||
public int Id { get; set; }
|
||||
}
|
||||
@@ -12,7 +12,7 @@ namespace YYApi.Communications
|
||||
/// <summary>
|
||||
/// 基础分页请求
|
||||
/// </summary>
|
||||
public class YYBasePageRequest
|
||||
public class SimApiBasePageRequest
|
||||
{
|
||||
public int Page { get; set; }
|
||||
public int Count { get; set; }
|
||||
@@ -2,12 +2,12 @@
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
|
||||
namespace YYApi.Communications
|
||||
namespace SimApi.Communications
|
||||
{
|
||||
/// <summary>
|
||||
/// 基础相应
|
||||
/// </summary>
|
||||
public class YYBaseResponse
|
||||
public class SimApiBaseResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 错误代码
|
||||
@@ -36,7 +36,7 @@ namespace YYApi.Communications
|
||||
/// <summary>
|
||||
/// 返回一个成功的空结果
|
||||
/// </summary>
|
||||
public YYBaseResponse()
|
||||
public SimApiBaseResponse()
|
||||
{
|
||||
SetCode(200);
|
||||
}
|
||||
@@ -46,7 +46,7 @@ namespace YYApi.Communications
|
||||
/// 返回指定代码的描述
|
||||
/// </summary>
|
||||
/// <param name="code">错误代码</param>
|
||||
public YYBaseResponse(int code)
|
||||
public SimApiBaseResponse(int code)
|
||||
{
|
||||
SetCode(code);
|
||||
}
|
||||
@@ -56,7 +56,7 @@ namespace YYApi.Communications
|
||||
/// </summary>
|
||||
/// <param name="code">错误代码</param>
|
||||
/// <param name="message">错误信息</param>
|
||||
public YYBaseResponse(int code, string message)
|
||||
public SimApiBaseResponse(int code, string message)
|
||||
{
|
||||
SetCodeMsg(code, message);
|
||||
}
|
||||
@@ -104,7 +104,7 @@ namespace YYApi.Communications
|
||||
/// 动态内容分页
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class YYBasePageResponse<T> : YYBaseResponse
|
||||
public class SimApiBasePageResponse<T> : SimApiBaseResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 动态内容列表
|
||||
@@ -122,7 +122,7 @@ namespace YYApi.Communications
|
||||
/// 动态Data返回
|
||||
/// </summary>
|
||||
/// <typeparam name="T"></typeparam>
|
||||
public class YYBaseResponse<T> : YYBaseResponse
|
||||
public class SimApiBaseResponse<T> : SimApiBaseResponse
|
||||
{
|
||||
/// <summary>
|
||||
/// 动态内容列表
|
||||
@@ -1,10 +1,10 @@
|
||||
using System;
|
||||
namespace YYApi.Communications
|
||||
namespace SimApi.Communications
|
||||
{
|
||||
/// <summary>
|
||||
/// 登录信息中间件
|
||||
/// </summary>
|
||||
public class YYLoginItem
|
||||
public class SimApiLoginItem
|
||||
{
|
||||
//登录用户的ID
|
||||
public int Id { get; set; }
|
||||
@@ -1,11 +1,12 @@
|
||||
using YYApi.Communications;
|
||||
using SimApi.Communications;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.AspNetCore.Mvc.ModelBinding;
|
||||
using System.Linq;
|
||||
using YYApi.Exceptions;
|
||||
using SimApi.Exceptions;
|
||||
using SimApi.Attributes;
|
||||
|
||||
namespace YYApi.Controllers
|
||||
namespace SimApi.Controllers
|
||||
{
|
||||
/// <summary>
|
||||
/// 基础控制器,所有控制器均继承本控制器
|
||||
@@ -13,12 +14,12 @@ namespace YYApi.Controllers
|
||||
/// 2. 报错返回
|
||||
/// 3. 错误回馈页面
|
||||
/// </summary>
|
||||
public class YYBaseController : Controller
|
||||
public class SimApiBaseController : Controller
|
||||
{
|
||||
/// <summary>
|
||||
/// 当前登录用户的ID
|
||||
/// </summary>
|
||||
protected YYLoginItem LoginInfo => (YYLoginItem)HttpContext.Items["LoginInfo"];
|
||||
protected SimApiLoginItem LoginInfo => (SimApiLoginItem)HttpContext.Items["LoginInfo"];
|
||||
|
||||
/// <summary>
|
||||
/// 验证请求参数
|
||||
@@ -46,9 +47,9 @@ namespace YYApi.Controllers
|
||||
/// <param name="code">错误代码</param>
|
||||
/// <param name="message">错误描述(若是常规错误,代码可自动带取描述)</param>
|
||||
/// <returns></returns>
|
||||
protected static void Error(int code = 500, string message = "")
|
||||
protected static void Error(int code = 500, string message = "服务器错误")
|
||||
{
|
||||
throw new YYApiException(code, message);
|
||||
throw new SimApiException(code, message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -57,7 +58,7 @@ namespace YYApi.Controllers
|
||||
/// <param name="condition">检测条件</param>
|
||||
/// <param name="code">错误代码</param>
|
||||
/// <param name="message">错误描述</param>
|
||||
protected static void ErrorWhen(bool condition, int code = 500, string message = "")
|
||||
protected static void ErrorWhen(bool condition, int code = 500, string message = "服务器错误")
|
||||
{
|
||||
if (condition)
|
||||
{
|
||||
@@ -71,28 +72,20 @@ namespace YYApi.Controllers
|
||||
/// <param name="condition">检测条件</param>
|
||||
/// <param name="code">错误代码</param>
|
||||
/// <param name="message">错误描述</param>
|
||||
protected static void ErrorWhenNull(object condition, int code = 404, string message = "请求的资源不存在")
|
||||
protected static void ErrorWhenNull(object condition, int code = 404, string message = "资源不存在")
|
||||
{
|
||||
ErrorWhen(condition == null, code, message);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 错误回馈页面
|
||||
/// 上传文件
|
||||
/// </summary>
|
||||
/// <param name="code">错误代码</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("exception/{code:int}")]
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public YYBaseResponse ExceptionHandler(int code)
|
||||
protected SimApiBaseResponse<string> UploadFile()
|
||||
{
|
||||
var response = new YYBaseResponse();
|
||||
response.SetCode(code);
|
||||
return response;
|
||||
return new SimApiBaseResponse<string>();
|
||||
}
|
||||
|
||||
protected YYBaseResponse<string> UploadFile()
|
||||
{
|
||||
return new YYBaseResponse<string>();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using SimApi.Attributes;
|
||||
using SimApi.Communications;
|
||||
using SimApi.Helpers;
|
||||
|
||||
namespace SimApi.Controllers
|
||||
{
|
||||
public class YYCommonController : SimApiBaseController
|
||||
{
|
||||
private SimApiAuth Auth { get; }
|
||||
|
||||
public YYCommonController(SimApiAuth auth)
|
||||
{
|
||||
Auth = auth;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 错误回馈页面
|
||||
/// </summary>
|
||||
/// <param name="code">错误代码</param>
|
||||
/// <returns></returns>
|
||||
[HttpGet("exception/{code:int}")]
|
||||
[ApiExplorerSettings(IgnoreApi = true)]
|
||||
public SimApiBaseResponse ExceptionHandler(int code)
|
||||
{
|
||||
var response = new SimApiBaseResponse();
|
||||
response.SetCode(code);
|
||||
return response;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 检测用户登陆的控制器
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("/auth/check"), SimApiDoc("认证", "检测登陆")]
|
||||
public SimApiBaseResponse<int> CheckLogin()
|
||||
{
|
||||
ErrorWhenNull(LoginInfo, 401);
|
||||
return new SimApiBaseResponse<int> { Data = LoginInfo.Id };
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 退出登陆
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[HttpPost("/auth/logout"), SimApiDoc("认证", "退出登陆")]
|
||||
public SimApiBaseResponse Logout()
|
||||
{
|
||||
string token = null;
|
||||
|
||||
if (Request.Headers.ContainsKey("Token"))
|
||||
{
|
||||
token = Request.Headers["Token"];
|
||||
}
|
||||
Auth.Logout(token);
|
||||
return new SimApiBaseResponse();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,14 @@
|
||||
using System;
|
||||
namespace YYApi.Exceptions
|
||||
namespace SimApi.Exceptions
|
||||
{
|
||||
/// <summary>
|
||||
/// Api错误捕获异常
|
||||
/// </summary>
|
||||
public class YYApiException : Exception
|
||||
public class SimApiException : Exception
|
||||
{
|
||||
public int Code { get; }
|
||||
|
||||
public YYApiException(int code, string message = "") : base(message)
|
||||
public SimApiException(int code, string message = "") : base(message)
|
||||
{
|
||||
Code = code;
|
||||
}
|
||||
@@ -2,18 +2,18 @@ using System;
|
||||
using System.Text.Json;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Caching.Distributed;
|
||||
using YYApi.Communications;
|
||||
using SimApi.Communications;
|
||||
|
||||
namespace YYApi.Helpers
|
||||
namespace SimApi.Helpers
|
||||
{
|
||||
/// <summary>
|
||||
/// 认证助手
|
||||
/// </summary>
|
||||
public class YYAuth
|
||||
public class SimApiAuth
|
||||
{
|
||||
private IDistributedCache Cache { get; }
|
||||
|
||||
public YYAuth(IDistributedCache cache)
|
||||
public SimApiAuth(IDistributedCache cache)
|
||||
{
|
||||
Cache = cache;
|
||||
}
|
||||
@@ -40,7 +40,7 @@ namespace YYApi.Helpers
|
||||
{
|
||||
uuid = Guid.NewGuid().ToString();
|
||||
}
|
||||
var loginItem = new YYLoginItem
|
||||
var loginItem = new SimApiLoginItem
|
||||
{
|
||||
Id = id,
|
||||
Type = type
|
||||
@@ -55,7 +55,10 @@ namespace YYApi.Helpers
|
||||
/// <param name="uuid">登陆标识</param>
|
||||
public void Logout(string uuid)
|
||||
{
|
||||
Cache.Remove(uuid);
|
||||
if (!string.IsNullOrEmpty(uuid))
|
||||
{
|
||||
Cache.Remove(uuid);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -2,9 +2,9 @@
|
||||
using System.IO;
|
||||
using Microsoft.AspNetCore.Hosting;
|
||||
|
||||
namespace YYApi.Helpers
|
||||
namespace SimApi.Helpers
|
||||
{
|
||||
public class YYUpload
|
||||
public class SimApiUpload
|
||||
{
|
||||
private string FilePathFolder = "/uploads/";
|
||||
public string FilePath
|
||||
@@ -28,12 +28,12 @@ namespace YYApi.Helpers
|
||||
|
||||
private IWebHostEnvironment Env { get; }
|
||||
|
||||
public YYUpload(IWebHostEnvironment env)
|
||||
public SimApiUpload(IWebHostEnvironment env)
|
||||
{
|
||||
Env = env;
|
||||
}
|
||||
|
||||
public class YYUploadInfo
|
||||
public class SimApiUploadInfo
|
||||
{
|
||||
public string Path { get; set; }
|
||||
public int Size { get; set; }
|
||||
@@ -47,7 +47,7 @@ namespace YYApi.Helpers
|
||||
/// <param name="path">存放路径</param>
|
||||
/// <param name="fileName">文件名</param>
|
||||
/// <returns></returns>
|
||||
public YYUploadInfo SaveFile(string base64, string ext = null, string path = null, string fileName = null)
|
||||
public SimApiUploadInfo SaveFile(string base64, string ext = null, string path = null, string fileName = null)
|
||||
{
|
||||
byte[] bt;
|
||||
var filePath = FilePath + path;
|
||||
@@ -85,7 +85,7 @@ namespace YYApi.Helpers
|
||||
/// <param name="fileName"></param>
|
||||
/// <param name="data"></param>
|
||||
/// <returns></returns>
|
||||
public YYUploadInfo WriteFile(string filePath, string fileName, byte[] data)
|
||||
public SimApiUploadInfo WriteFile(string filePath, string fileName, byte[] data)
|
||||
{
|
||||
var realPath = Directory.GetCurrentDirectory() + "/wwwroot" + filePath;
|
||||
if (!Directory.Exists(realPath))
|
||||
@@ -93,7 +93,7 @@ namespace YYApi.Helpers
|
||||
Directory.CreateDirectory(realPath);
|
||||
}
|
||||
File.WriteAllBytes(realPath + fileName, data);
|
||||
return new YYUploadInfo
|
||||
return new SimApiUploadInfo
|
||||
{
|
||||
Path = filePath + fileName,
|
||||
Size = data.Length
|
||||
@@ -3,9 +3,9 @@ using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
namespace YYApi.Helpers
|
||||
namespace SimApi.Helpers
|
||||
{
|
||||
public static class YYUtil
|
||||
public static class SimApiUtil
|
||||
{
|
||||
/// <summary>
|
||||
/// 检测手机号是否正确
|
||||
@@ -1,124 +0,0 @@
|
||||
using System;
|
||||
using Hangfire.Dashboard;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using StackExchange.Redis;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using System.Security.Cryptography;
|
||||
|
||||
namespace YYApi.JobService
|
||||
{
|
||||
/// <summary>
|
||||
/// Redis缓存Key定义
|
||||
/// </summary>
|
||||
public struct CacheKey
|
||||
{
|
||||
public const string HangfireDashboardAuthPrefix = "{hangfire}:dashboard:auth:";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// HangFire Dashboard Digest认证.
|
||||
/// </summary>
|
||||
public class YYHFDashboardAuth : IDashboardAuthorizationFilter
|
||||
{
|
||||
private IConfiguration _config { get; }
|
||||
private IDatabase _redis { get; }
|
||||
public YYHFDashboardAuth(IConfiguration config, IDatabase redis)
|
||||
{
|
||||
_redis = redis;
|
||||
_config = config;
|
||||
}
|
||||
|
||||
public bool Authorize(DashboardContext context)
|
||||
{
|
||||
var http = context.GetHttpContext();
|
||||
if (http.Request.Headers.ContainsKey("Authorization"))
|
||||
{
|
||||
var authObj = _processAuthHeader(http.Request.Headers["Authorization"].ToString());
|
||||
if (http.Request.QueryString.ToString().Contains("logout"))
|
||||
{
|
||||
_redis.KeyDelete(CacheKey.HangfireDashboardAuthPrefix + authObj["opaque"]);
|
||||
_redirect(http);
|
||||
return true;
|
||||
}
|
||||
if (authObj["username"] == _config["Hangfire:User"])
|
||||
{
|
||||
var a1 = _md5(string.Format("{0}:Need Login:{1}", authObj["username"], _config["Hangfire:Pass"]));
|
||||
var a2 = _md5(string.Format("{0}:{1}", http.Request.Method, authObj["uri"]));
|
||||
var nonce = _redis.StringGet(CacheKey.HangfireDashboardAuthPrefix + authObj["opaque"]);
|
||||
var validCode = _md5(string.Format("{0}:{1}:{2}:{3}:{4}:{5}", a1, nonce, authObj["nc"], authObj["cnonce"], authObj["qop"], a2));
|
||||
if (authObj["response"] == validCode)
|
||||
{
|
||||
_redis.StringSet(CacheKey.HangfireDashboardAuthPrefix + authObj["opaque"], nonce, new TimeSpan(0, 5, 0));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
_challenge(http);
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 生成401认证header
|
||||
/// </summary>
|
||||
/// <returns>The challenge.</returns>
|
||||
private void _challenge(HttpContext http)
|
||||
{
|
||||
var response = http.Response;
|
||||
var guid = Guid.NewGuid().ToString();
|
||||
var opaque = _md5(guid);
|
||||
_redis.StringSet(CacheKey.HangfireDashboardAuthPrefix + opaque, guid, new TimeSpan(0, 0, 30));
|
||||
response.StatusCode = 401;
|
||||
response.Headers.Add("WWW-Authenticate", string.Format("Digest realm=\"Need Login\",qop=\"auth\",nonce=\"{0}\",opaque=\"{1}\"", guid, opaque));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 跳转到页面不附加参数
|
||||
/// </summary>
|
||||
/// <param name="http">Http.</param>
|
||||
private void _redirect(HttpContext http)
|
||||
{
|
||||
var response = http.Response;
|
||||
response.StatusCode = 302;
|
||||
response.Headers.Add("Location", (http.Request.PathBase + http.Request.Path).ToString());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 处理DigestHeader中的参数为字典
|
||||
/// </summary>
|
||||
/// <returns>The auth header.</returns>
|
||||
/// <param name="authData">Auth data.</param>
|
||||
private Dictionary<string, string> _processAuthHeader(string authData)
|
||||
{
|
||||
var authDataArray = authData.Replace("Digest ", string.Empty).Replace("\"", string.Empty).Split(", ");
|
||||
var authDic = new Dictionary<string, string>();
|
||||
foreach (var item in authDataArray)
|
||||
{
|
||||
var tmp = item.Split("=", 2);
|
||||
authDic.Add(tmp[0], tmp[1]);
|
||||
}
|
||||
return authDic;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 计算字符串32位MD5
|
||||
/// </summary>
|
||||
/// <returns>The md5.</returns>
|
||||
/// <param name="source">Source.</param>
|
||||
private string _md5(string source)
|
||||
{
|
||||
byte[] sor = Encoding.UTF8.GetBytes(source);
|
||||
var md5 = MD5.Create();
|
||||
byte[] result = md5.ComputeHash(sor);
|
||||
StringBuilder strbul = new StringBuilder(40);
|
||||
for (int i = 0; i < result.Length; i++)
|
||||
{
|
||||
strbul.Append(result[i].ToString("x2"));//加密结果"x2"结果为32位,"x3"结果为48位,"x4"结果为64位
|
||||
|
||||
}
|
||||
return strbul.ToString();
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
using System;
|
||||
namespace YYApi.JobService
|
||||
{
|
||||
public class JobDashboardConfig
|
||||
{
|
||||
public string Path { get; set; }
|
||||
public string Username { get; set; }
|
||||
public string Password { get; set; }
|
||||
}
|
||||
}
|
||||
@@ -1,10 +0,0 @@
|
||||
using System;
|
||||
namespace YYApi.JobService
|
||||
{
|
||||
public class JobStorage
|
||||
{
|
||||
public JobStorage()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2,18 +2,18 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using Microsoft.Extensions.Caching.Distributed;
|
||||
using YYApi.Communications;
|
||||
using SimApi.Communications;
|
||||
|
||||
namespace YYApi.Middlewares
|
||||
namespace SimApi.Middlewares
|
||||
{
|
||||
/// <summary>
|
||||
/// 认证信息获取中间件
|
||||
/// </summary>
|
||||
public class YYAuthMiddleware
|
||||
public class SimApiAuthMiddleware
|
||||
{
|
||||
private RequestDelegate Next { get; }
|
||||
|
||||
public YYAuthMiddleware(RequestDelegate next)
|
||||
public SimApiAuthMiddleware(RequestDelegate next)
|
||||
{
|
||||
Next = next;
|
||||
}
|
||||
@@ -31,10 +31,10 @@ namespace YYApi.Middlewares
|
||||
var login = cache.GetString(token);
|
||||
if (login != null)
|
||||
{
|
||||
httpContext.Items.Add("LoginInfo", JsonSerializer.Deserialize<YYLoginItem>(login));
|
||||
httpContext.Items.Add("LoginInfo", JsonSerializer.Deserialize<SimApiLoginItem>(login));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return Next(httpContext);
|
||||
}
|
||||
}
|
||||
@@ -1,21 +1,21 @@
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Http;
|
||||
using YYApi.Communications;
|
||||
using SimApi.Communications;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using YYApi.Exceptions;
|
||||
using SimApi.Exceptions;
|
||||
|
||||
namespace YYApi.Middlewares
|
||||
namespace SimApi.Middlewares
|
||||
{
|
||||
/// <summary>
|
||||
/// 异常处理中间件
|
||||
/// </summary>
|
||||
public class YYExceptionMiddleware
|
||||
public class SimApiExceptionMiddleware
|
||||
{
|
||||
private RequestDelegate Next { get; }
|
||||
private ILogger<YYExceptionMiddleware> Log { get; }
|
||||
private ILogger<SimApiExceptionMiddleware> Log { get; }
|
||||
|
||||
public YYExceptionMiddleware(RequestDelegate next, ILogger<YYExceptionMiddleware> log)
|
||||
public SimApiExceptionMiddleware(RequestDelegate next, ILogger<SimApiExceptionMiddleware> log)
|
||||
{
|
||||
Log = log;
|
||||
Next = next;
|
||||
@@ -23,14 +23,26 @@ namespace YYApi.Middlewares
|
||||
|
||||
public async Task InvokeAsync(HttpContext context)
|
||||
{
|
||||
var response = new YYBaseResponse();
|
||||
if (context.Request.Headers.ContainsKey("Query-Id"))
|
||||
{
|
||||
context.Response.Headers["Query-Id"] = context.Request.Headers["Query-Id"];
|
||||
}
|
||||
|
||||
var response = new SimApiBaseResponse();
|
||||
try
|
||||
{
|
||||
await Next(context);
|
||||
}
|
||||
catch (YYApiException ex)
|
||||
catch (SimApiException ex)
|
||||
{
|
||||
response.SetCodeMsg(ex.Code, ex.Message);
|
||||
if (string.IsNullOrEmpty(ex.Message))
|
||||
{
|
||||
response.SetCode(ex.Code);
|
||||
}
|
||||
else
|
||||
{
|
||||
response.SetCodeMsg(ex.Code, ex.Message);
|
||||
}
|
||||
ErrorResponse(context, response);
|
||||
}
|
||||
catch (Exception ex)
|
||||
@@ -47,7 +59,7 @@ namespace YYApi.Middlewares
|
||||
/// </summary>
|
||||
/// <param name="context"></param>
|
||||
/// <param name="response"></param>
|
||||
private void ErrorResponse(HttpContext context, YYBaseResponse response)
|
||||
private void ErrorResponse(HttpContext context, SimApiBaseResponse response)
|
||||
{
|
||||
context.Response.StatusCode = 200;
|
||||
context.Response.Headers.Add("Content-Type", "application/json");
|
||||
@@ -9,15 +9,16 @@
|
||||
|
||||
```C#
|
||||
using Models;
|
||||
using SimApi.Controllers;
|
||||
|
||||
namespace Controllers
|
||||
{
|
||||
public class BaseController : YYApi.Controllers.BaseController
|
||||
public class BaseController : SimApiBaseController
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取登录用户信息
|
||||
/// </summary>
|
||||
protected LoginInfoItem LoginInfo => (LoginInfoItem) HttpContext.Items["LoginInfo"];
|
||||
protected SimApiLoginInfoItem LoginInfo => (SimApiLoginInfoItem) HttpContext.Items["LoginInfo"];
|
||||
}
|
||||
}
|
||||
```
|
||||
@@ -27,32 +28,32 @@ namespace Controllers
|
||||
```C#
|
||||
#Startup.cs
|
||||
|
||||
services.AddYYDoc("文档名称", "文档描述");
|
||||
services.AddSimApiDoc("文档名称", "文档描述");
|
||||
|
||||
app.UseYYDoc("名称",SubmitMethod[])
|
||||
app.UseSimApiDoc("名称",SubmitMethod[])
|
||||
|
||||
#控制器中可以直接使用特性
|
||||
|
||||
[YYDoc("分组","名称")]
|
||||
[SimApiDoc("分组","名称")]
|
||||
```
|
||||
|
||||
3. 简单的基于Redis的登录TOKEN服务
|
||||
|
||||
```C#
|
||||
#Startup.cs
|
||||
service.AddYYAuth();
|
||||
service.AddSimApiAuth();
|
||||
```
|
||||
添加时候, 可以从DI中获取 Auth 类,调用 Auth.Set(int,string) 将用户ID/类型和生成的Token绑定,本方法返回缓存中的Key名称
|
||||
|
||||
```C#
|
||||
#Startup.cs
|
||||
app.UseYYAuth();
|
||||
app.UseSimApiAuth();
|
||||
```
|
||||
调用本中间件,然后再需要登录认证的地方,使用 [YYAuth] 特性,即可完成检测登录相关的操作,
|
||||
如果需要获取用户的ID, 只需要 直接使用 LoginId 属性即可获取
|
||||
|
||||
4. 统一返回
|
||||
所有Response 均需要继承 BaseResponse类
|
||||
所有Response 均需要继承 SimApiBaseResponse类
|
||||
|
||||
|
||||
5. 异常处理
|
||||
@@ -60,9 +61,5 @@ app.UseYYAuth();
|
||||
|
||||
```C#
|
||||
#Startup.cs
|
||||
app.UseYYException();
|
||||
```
|
||||
|
||||
|
||||
### TODO:
|
||||
1. 增加HANGFIRE 支持redis和sqlite 存储, 支持 基于其他系统的TOKEN认证和独立账号密码认证
|
||||
app.UseSimApiException();
|
||||
```
|
||||
@@ -1,34 +1,34 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework>netcoreapp5.0</TargetFramework>
|
||||
<OutputType>Library</OutputType>
|
||||
<PackOnBuild>true</PackOnBuild>
|
||||
<Version>0.2.3</Version>
|
||||
<Authors>xRain@YYTech</Authors>
|
||||
<Authors>xRain@SimcuTeam</Authors>
|
||||
<Description>AspNetCore一个方便的API文档,捕获异常,统一输入输出的API类库</Description>
|
||||
<PackageId>YY-Tech.YYApi</PackageId>
|
||||
<PackageId>Simcu.SimApi</PackageId>
|
||||
<IsPackable>true</IsPackable>
|
||||
<SymbolPackageFormat>snupkg</SymbolPackageFormat>
|
||||
<IncludeSymbols>true</IncludeSymbols>
|
||||
<ReleaseVersion>5.0.0</ReleaseVersion>
|
||||
<SynchReleaseVersion>false</SynchReleaseVersion>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<PackageVersion>5.0.2</PackageVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Condition=" '$(RunConfiguration)' == 'YYApi' " />
|
||||
<ItemGroup>
|
||||
<Folder Include="Helpers\" />
|
||||
<Folder Include="Communications\" />
|
||||
<Folder Include="Controllers\" />
|
||||
<Folder Include="JobService\" />
|
||||
<Folder Include="Middlewares\" />
|
||||
<Folder Include="Attributes\" />
|
||||
<Folder Include="Exceptions\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="5.5.1" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="5.5.1" />
|
||||
<PackageReference Include="HangFire.Core" Version="1.7.11" />
|
||||
<PackageReference Include="Hangfire.AspNetCore" Version="1.7.11" />
|
||||
<PackageReference Include="Hangfire.Console" Version="1.4.2" />
|
||||
<PackageReference Include="Hangfire.Redis.StackExchange" Version="1.8.4" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.Annotations" Version="5.6.3" />
|
||||
<PackageReference Include="Swashbuckle.AspNetCore.SwaggerUI" Version="5.6.3" />
|
||||
</ItemGroup>
|
||||
<ProjectExtensions>
|
||||
<MonoDevelop>
|
||||
@@ -1,44 +1,47 @@
|
||||
using System;
|
||||
using YYApi.Helpers;
|
||||
using SimApi.Helpers;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Swashbuckle.AspNetCore.SwaggerUI;
|
||||
using YYApi.Middlewares;
|
||||
using SimApi.Middlewares;
|
||||
|
||||
namespace YYApi
|
||||
namespace SimApi
|
||||
{
|
||||
/// <summary>
|
||||
/// 加入系统的扩展信息
|
||||
/// </summary>
|
||||
public static class Extensions
|
||||
{
|
||||
public static string DocumentTitle = "";
|
||||
public static string DocumentDescription = "";
|
||||
|
||||
//**********快捷添加**************
|
||||
|
||||
/// <summary>
|
||||
/// 添加整个YYAPI,同时增加CORS规则
|
||||
/// 添加整个SimAPI,同时增加CORS规则
|
||||
/// </summary>
|
||||
/// <param name="builder"></param>
|
||||
/// <param name="title"></param>
|
||||
/// <param name="description"></param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddYYApi(this IServiceCollection builder, string title,
|
||||
public static IServiceCollection AddSimApi(this IServiceCollection builder, string title,
|
||||
string description = null)
|
||||
{
|
||||
return builder.AddYYAuth().AddYYDoc(title, description).AddCors().AddYYUpload();
|
||||
return builder.AddSimApiAuth().AddSimApiDoc(title, description).AddCors().AddSimApiUpload();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用所有YYApi自定义中间件
|
||||
/// 使用所有SimApi自定义中间件
|
||||
/// </summary>
|
||||
/// <param name="builder"></param>
|
||||
/// <param name="title"></param>
|
||||
/// <param name="staticFileroot"></param>
|
||||
/// <param name="submitMethods"></param>
|
||||
/// <returns></returns>
|
||||
public static IApplicationBuilder UseYYApi(this IApplicationBuilder builder, string title = "API文档", params SubmitMethod[] submitMethods)
|
||||
public static IApplicationBuilder UseSimApi(this IApplicationBuilder builder, params SubmitMethod[] submitMethods)
|
||||
{
|
||||
return builder.UseYYException().UseYYDoc(title, submitMethods).UseMiddleware<YYAuthMiddleware>().UseCors(x => x.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin()).UseYYUpload();
|
||||
return builder.UseSimApiException().UseSimApiDoc(submitMethods).UseMiddleware<SimApiAuthMiddleware>().UseCors(x => x.AllowAnyHeader().AllowAnyMethod().AllowAnyOrigin()).UseSimApiUpload();
|
||||
}
|
||||
|
||||
|
||||
@@ -50,9 +53,9 @@ namespace YYApi
|
||||
/// </summary>
|
||||
/// <param name="builder"></param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddYYAuth(this IServiceCollection builder)
|
||||
public static IServiceCollection AddSimApiAuth(this IServiceCollection builder)
|
||||
{
|
||||
return builder.AddScoped<YYAuth>();
|
||||
return builder.AddScoped<SimApiAuth>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -60,9 +63,9 @@ namespace YYApi
|
||||
/// </summary>
|
||||
/// <param name="builder"></param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddYYUpload(this IServiceCollection builder)
|
||||
public static IServiceCollection AddSimApiUpload(this IServiceCollection builder)
|
||||
{
|
||||
return builder.AddSingleton<YYUpload>();
|
||||
return builder.AddSingleton<SimApiUpload>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -72,12 +75,14 @@ namespace YYApi
|
||||
/// <param name="title">文档标题</param>
|
||||
/// <param name="description">文档描述</param>
|
||||
/// <returns></returns>
|
||||
public static IServiceCollection AddYYDoc(this IServiceCollection builder, string title,
|
||||
public static IServiceCollection AddSimApiDoc(this IServiceCollection builder, string title,
|
||||
string description = null)
|
||||
{
|
||||
DocumentTitle = title;
|
||||
DocumentDescription = description;
|
||||
return builder.AddSwaggerGen(x =>
|
||||
{
|
||||
x.SwaggerDoc("api", new OpenApiInfo { Title = title, Description = description });
|
||||
x.SwaggerDoc("api", new OpenApiInfo { Title = DocumentTitle, Description = DocumentDescription });
|
||||
x.EnableAnnotations();
|
||||
x.AddSecurityRequirement(new OpenApiSecurityRequirement
|
||||
{
|
||||
@@ -100,9 +105,9 @@ namespace YYApi
|
||||
/// </summary>
|
||||
/// <param name="builder"></param>
|
||||
/// <returns></returns>
|
||||
public static IApplicationBuilder UseYYException(this IApplicationBuilder builder)
|
||||
public static IApplicationBuilder UseSimApiException(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseMiddleware<YYExceptionMiddleware>();
|
||||
return builder.UseMiddleware<SimApiExceptionMiddleware>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -110,7 +115,7 @@ namespace YYApi
|
||||
/// </summary>
|
||||
/// <param name="builder"></param>
|
||||
/// <returns></returns>
|
||||
public static IApplicationBuilder UseYYUpload(this IApplicationBuilder builder)
|
||||
public static IApplicationBuilder UseSimApiUpload(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseStaticFiles(new StaticFileOptions
|
||||
{
|
||||
@@ -126,14 +131,13 @@ namespace YYApi
|
||||
/// <param name="title">文档标题</param>
|
||||
/// <param name="submitMethods">文档支持的提交方式(如果不指定,默认使用POST)</param>
|
||||
/// <returns></returns>
|
||||
public static IApplicationBuilder UseYYDoc(this IApplicationBuilder builder, string title,
|
||||
params SubmitMethod[] submitMethods)
|
||||
public static IApplicationBuilder UseSimApiDoc(this IApplicationBuilder builder, params SubmitMethod[] submitMethods)
|
||||
{
|
||||
return builder.UseSwagger(x => x.RouteTemplate = "docs/{documentName}.json").UseSwaggerUI(x =>
|
||||
{
|
||||
x.RoutePrefix = "docs";
|
||||
x.DocumentTitle = title;
|
||||
x.SwaggerEndpoint("/docs/api.json", name: title);
|
||||
x.DocumentTitle = DocumentTitle;
|
||||
x.SwaggerEndpoint("/docs/api.json", name: DocumentTitle);
|
||||
x.EnableValidator();
|
||||
if (submitMethods.Length > 0)
|
||||
{
|
||||
@@ -156,10 +160,9 @@ namespace YYApi
|
||||
/// <param name="title">文档标题</param>
|
||||
/// <param name="submitMethods">API提交方式定义</param>
|
||||
/// <returns></returns>
|
||||
public static IApplicationBuilder UseYYDocEx(this IApplicationBuilder builder, string title = "API文档",
|
||||
params SubmitMethod[] submitMethods)
|
||||
public static IApplicationBuilder UseSimApiDocEx(this IApplicationBuilder builder, params SubmitMethod[] submitMethods)
|
||||
{
|
||||
return builder.UseYYException().UseYYDoc(title, submitMethods);
|
||||
return builder.UseSimApiException().UseSimApiDoc(submitMethods);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -167,9 +170,9 @@ namespace YYApi
|
||||
/// </summary>
|
||||
/// <param name="builder"></param>
|
||||
/// <returns></returns>
|
||||
public static IApplicationBuilder UseYYAuth(this IApplicationBuilder builder)
|
||||
public static IApplicationBuilder UseSimApiAuth(this IApplicationBuilder builder)
|
||||
{
|
||||
return builder.UseMiddleware<YYAuthMiddleware>();
|
||||
return builder.UseMiddleware<SimApiAuthMiddleware>();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user