init
This commit is contained in:
77
DouyinApi.Gateway/Extensions/ApiResponseHandler.cs
Normal file
77
DouyinApi.Gateway/Extensions/ApiResponseHandler.cs
Normal file
@@ -0,0 +1,77 @@
|
||||
using DouyinApi.Model;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DouyinApi.Gateway.Extensions
|
||||
{
|
||||
/// <summary>
|
||||
/// 这里不需要,目前集成的是 DouyinApi.Extensions 下的接口处理器
|
||||
/// 但是你可以单独在网关中使用这个。
|
||||
/// </summary>
|
||||
public class ApiResponseHandler : DelegatingHandler
|
||||
{
|
||||
JsonSerializerSettings jsonSerializerSettings = new JsonSerializerSettings()
|
||||
{
|
||||
ContractResolver = new CamelCasePropertyNamesContractResolver()
|
||||
};
|
||||
|
||||
protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
{
|
||||
var response = await base.SendAsync(request, cancellationToken);
|
||||
var contentType = response.Content.Headers.ContentType?.MediaType ?? "";
|
||||
if (!contentType.Equals("application/json")) return response;
|
||||
|
||||
dynamic result = null;
|
||||
var resultStr = await response.Content.ReadAsStringAsync();
|
||||
try
|
||||
{
|
||||
result = JsonConvert.DeserializeObject<dynamic>(resultStr);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return response;
|
||||
}
|
||||
|
||||
if (result != null && result.code == 500) resultStr = result.msg.ToString();
|
||||
|
||||
var apiResponse = new ApiResponse(StatusCode.CODE200).MessageModel;
|
||||
if (response.StatusCode != HttpStatusCode.OK || result.code == (int)HttpStatusCode.InternalServerError)
|
||||
{
|
||||
var exception = new Exception(resultStr);
|
||||
apiResponse = new ApiResponse(StatusCode.CODE500).MessageModel;
|
||||
}
|
||||
else if (result.code == (int)HttpStatusCode.Unauthorized)
|
||||
{
|
||||
apiResponse = new ApiResponse(StatusCode.CODE401).MessageModel;
|
||||
|
||||
}
|
||||
else if (result.code == (int)HttpStatusCode.Forbidden)
|
||||
{
|
||||
apiResponse = new ApiResponse(StatusCode.CODE403).MessageModel;
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
var statusCode = apiResponse.status == 500 ? HttpStatusCode.InternalServerError
|
||||
: apiResponse.status == 401 ? HttpStatusCode.Unauthorized
|
||||
: apiResponse.status == 403 ? HttpStatusCode.Forbidden
|
||||
: HttpStatusCode.OK;
|
||||
|
||||
response.StatusCode = statusCode;
|
||||
response.Content = new StringContent(JsonConvert.SerializeObject(apiResponse, jsonSerializerSettings), Encoding.UTF8, "application/json");
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
53
DouyinApi.Gateway/Extensions/CustomAuthenticationHandler.cs
Normal file
53
DouyinApi.Gateway/Extensions/CustomAuthenticationHandler.cs
Normal file
@@ -0,0 +1,53 @@
|
||||
using Microsoft.AspNetCore.Authentication;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.Net.Http.Headers;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Security.Claims;
|
||||
using System.Text.Encodings.Web;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DouyinApi.Gateway.Extensions
|
||||
{
|
||||
public class CustomAuthenticationHandler : AuthenticationHandler<AuthenticationSchemeOptions>
|
||||
{
|
||||
public CustomAuthenticationHandler(IOptionsMonitor<AuthenticationSchemeOptions> options,
|
||||
ILoggerFactory logger,
|
||||
UrlEncoder encoder,
|
||||
ISystemClock clock) : base(options, logger, encoder, clock)
|
||||
{
|
||||
}
|
||||
|
||||
protected override async Task<AuthenticateResult> HandleAuthenticateAsync()
|
||||
{
|
||||
// 可以查询数据库等操作
|
||||
// 获取当前用户不能放到token中的私密信息
|
||||
var userPhone = "15010000000";
|
||||
|
||||
var claims = new List<Claim>()
|
||||
{
|
||||
new Claim("user-phone", userPhone),
|
||||
new Claim("gw-sign", "gw")
|
||||
};
|
||||
|
||||
var principal = new ClaimsPrincipal(new ClaimsIdentity(claims, Scheme.Name));
|
||||
var ticket = new AuthenticationTicket(principal, Scheme.Name);
|
||||
await Task.CompletedTask;
|
||||
return AuthenticateResult.Success(ticket);
|
||||
}
|
||||
|
||||
protected virtual string GetTokenStringFromHeader()
|
||||
{
|
||||
var token = string.Empty;
|
||||
string authorization = Request.Headers[HeaderNames.Authorization];
|
||||
|
||||
if (!string.IsNullOrEmpty(authorization) && authorization.StartsWith($"Bearer ", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
token = authorization["Bearer ".Length..].Trim();
|
||||
}
|
||||
|
||||
return token;
|
||||
}
|
||||
}
|
||||
}
|
||||
34
DouyinApi.Gateway/Extensions/CustomOcelotSetup.cs
Normal file
34
DouyinApi.Gateway/Extensions/CustomOcelotSetup.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
using DouyinApi.Extensions;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Ocelot.DependencyInjection;
|
||||
using Ocelot.Middleware;
|
||||
using Ocelot.Provider.Nacos;
|
||||
using Ocelot.Provider.Polly;
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DouyinApi.Gateway.Extensions
|
||||
{
|
||||
public static class CustomOcelotSetup
|
||||
{
|
||||
public static void AddCustomOcelotSetup(this IServiceCollection services)
|
||||
{
|
||||
if (services == null) throw new ArgumentNullException(nameof(services));
|
||||
|
||||
services.AddAuthentication_JWTSetup();
|
||||
services.AddOcelot()
|
||||
.AddDelegatingHandler<CustomResultHandler>()
|
||||
//.AddNacosDiscovery()
|
||||
//.AddConsul()
|
||||
.AddPolly();
|
||||
}
|
||||
|
||||
public static async Task<IApplicationBuilder> UseCustomOcelotMildd(this IApplicationBuilder app)
|
||||
{
|
||||
await app.UseOcelot();
|
||||
return app;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
62
DouyinApi.Gateway/Extensions/CustomResultHandler.cs
Normal file
62
DouyinApi.Gateway/Extensions/CustomResultHandler.cs
Normal file
@@ -0,0 +1,62 @@
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Serialization;
|
||||
using System;
|
||||
using System.Net;
|
||||
using System.Net.Http;
|
||||
using System.Text;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace DouyinApi.Gateway.Extensions
|
||||
{
|
||||
public class CustomResultHandler : DelegatingHandler
|
||||
{
|
||||
JsonSerializerSettings _camelSettings = new JsonSerializerSettings() { ContractResolver = new CamelCasePropertyNamesContractResolver() };
|
||||
|
||||
protected async override Task<HttpResponseMessage> SendAsync(HttpRequestMessage request, CancellationToken cancellationToken)
|
||||
{
|
||||
var response = await base.SendAsync(request, cancellationToken);
|
||||
var contentType = response.Content.Headers.ContentType?.MediaType ?? "";
|
||||
if (!contentType.Equals("application/json")) return response;
|
||||
|
||||
dynamic result = null;
|
||||
var resultStr = await response.Content.ReadAsStringAsync();
|
||||
try
|
||||
{
|
||||
Console.WriteLine(resultStr);
|
||||
result = JsonConvert.DeserializeObject<dynamic>(resultStr);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return response;
|
||||
}
|
||||
|
||||
if (result != null && result.errorCode == 500) resultStr = result.message.ToString();
|
||||
|
||||
var exception = new Exception(resultStr);
|
||||
|
||||
if (response.StatusCode == HttpStatusCode.InternalServerError || result.errorCode == (int)HttpStatusCode.InternalServerError)
|
||||
{
|
||||
var apiResult = new
|
||||
{
|
||||
Result = false,
|
||||
Message = "服务器内部错误",
|
||||
ErrorCode = (int)HttpStatusCode.InternalServerError,
|
||||
Data = new
|
||||
{
|
||||
exception.Message,
|
||||
exception.StackTrace
|
||||
}
|
||||
};
|
||||
response.Content = new StringContent(JsonConvert.SerializeObject(apiResult, _camelSettings), Encoding.UTF8, "application/json");
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
|
||||
return response;
|
||||
}
|
||||
}
|
||||
}
|
||||
81
DouyinApi.Gateway/Extensions/CustomSwaggerSetup.cs
Normal file
81
DouyinApi.Gateway/Extensions/CustomSwaggerSetup.cs
Normal file
@@ -0,0 +1,81 @@
|
||||
using DouyinApi.Common;
|
||||
using DouyinApi.Extensions.Middlewares;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Microsoft.OpenApi.Models;
|
||||
using Swashbuckle.AspNetCore.Filters;
|
||||
using Swashbuckle.AspNetCore.SwaggerUI;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Reflection;
|
||||
using static DouyinApi.Extensions.CustomApiVersion;
|
||||
namespace DouyinApi.Gateway.Extensions
|
||||
{
|
||||
public static class CustomSwaggerSetup
|
||||
{
|
||||
public static void AddCustomSwaggerSetup(this IServiceCollection services)
|
||||
{
|
||||
if (services == null) throw new ArgumentNullException(nameof(services));
|
||||
|
||||
var basePath = AppContext.BaseDirectory;
|
||||
|
||||
services.AddMvc(option => option.EnableEndpointRouting = false);
|
||||
|
||||
services.AddSwaggerGen(c =>
|
||||
{
|
||||
c.SwaggerDoc("v1", new OpenApiInfo
|
||||
{
|
||||
Version = "v1",
|
||||
Title = "自定义网关 接口文档",
|
||||
});
|
||||
|
||||
var xmlPath = Path.Combine(basePath, "DouyinApi.Gateway.xml");
|
||||
c.IncludeXmlComments(xmlPath, true);
|
||||
|
||||
c.OperationFilter<AddResponseHeadersFilter>();
|
||||
c.OperationFilter<AppendAuthorizeToSummaryOperationFilter>();
|
||||
|
||||
c.OperationFilter<SecurityRequirementsOperationFilter>();
|
||||
|
||||
c.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
|
||||
{
|
||||
Description = "JWT授权(数据将在请求头中进行传输) 直接在下框中输入Bearer {token}(注意两者之间是一个空格)\"",
|
||||
Name = "Authorization",
|
||||
In = ParameterLocation.Header,
|
||||
Type = SecuritySchemeType.ApiKey
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
public static void UseCustomSwaggerMildd(this IApplicationBuilder app, Func<Stream> streamHtml)
|
||||
{
|
||||
if (app == null) throw new ArgumentNullException(nameof(app));
|
||||
|
||||
var apis = new List<string> { "blog-svc" };
|
||||
app.UseSwagger();
|
||||
app.UseSwaggerUI(c =>
|
||||
{
|
||||
c.SwaggerEndpoint($"/swagger/v1/swagger.json", "gateway");
|
||||
apis.ForEach(m =>
|
||||
{
|
||||
c.SwaggerEndpoint($"/swagger/apiswg/{m}/swagger.json", m);
|
||||
});
|
||||
|
||||
|
||||
if (streamHtml.Invoke() == null)
|
||||
{
|
||||
var msg = "index.html的属性,必须设置为嵌入的资源";
|
||||
throw new Exception(msg);
|
||||
}
|
||||
|
||||
c.IndexStream = streamHtml;
|
||||
|
||||
c.RoutePrefix = "";
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user