.NET CORE 中间件
一、中间件分为三种:
//所有中间件就是委托 这是第一种形式的
app.Use(async (context, next) =>
{
await context.Response.WriteAsync("one");
await next(); //放行
await context.Response.WriteAsync("three");
});
// 第二种形式,中间件的终结点,如果遇到,就会返回
app.Run(async context =>
{
await context.Response.WriteAsync("two");
});
二、Net Core之自定义组件
1. Core 中提供了好多的中间件,大致的分为三种,一种是自定义中间件,一种是需要需要configure中注入,另外一种是同时需要在configureService中进行注入的中间件。具体如下:
using Focus.Infra.Response;
using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using System;
using System.Linq;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
namespace Focus.Infra.JwtAuth
{
/// <summary>
/// 按照约束来创建
/// 具有类型为RequestDelegate的参数的公共构造函数
/// 同时具有名为Invoke或者InvokeAsync的公共方法,这个方法必须满足两个条件:
/// 1.返回Task; 2.接收类型为HttpContext的第一个参数
/// Token处理中间件
/// </summary>
public abstract class AuthMiddleware<T> where T:class
{
private readonly RequestDelegate _next;
private readonly IAuthTokenService _authTokenService;
private static string _emptyCode = String.Empty;
private static string _timeError = String.Empty;
/// <summary>
/// 构造函数注入
/// </summary>
/// <param name="next"></param>
/// <param name="authTokenService"></param>
public AuthMiddleware(RequestDelegate next, IAuthTokenService authTokenService)
{
try
{
if(next == null || authTokenService == null)
{
throw new ArgumentException();
}
Result res = new Result();
res.Code = Code.ValidationFail;
res.Msg = "Pass in a token";
res.Data = false;
_emptyCode = JsonConvert.SerializeObject(res).ToLower();
res.Msg = "Token token error or expired, please login again";
_timeError = _emptyCode;
_next = next; //中间件必须调用改方法,不然该中间件就属于一个终结点,就会从次中间件直接返回。
_authTokenService = authTokenService;
}
catch(Exception e)
{
throw e;
}
}
/// <summary>
/// 中间件逻辑Invoke执行
/// </summary>
/// <param name="context"></param>
/// <returns></returns>
public async Task Invoke(HttpContext context)
{
if (context.Request.Method == "OPTIONS"
|| Regex.Match(context.Request.Path, "swagger").Success
|| PathUri(context))
{
await _next(context);
}
else if (context.Request.Headers.ContainsKey("token"))
{
var token = context.Request.Headers["token"].FirstOrDefault();
if (string.IsNullOrEmpty(token))
{
context.Response.Headers.Add("access-control-allow-credentials", "true");
context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
context.Response.Headers.Add("content-type", "application/json; charset=utf-8");
context.Response.StatusCode = 200;
await context.Response.WriteAsync(_emptyCode);
}
else
{
var user = await _authTokenService.GetUserByToken<T>(token);
if (user != null)
{
await _next(context);
}
else
{
context.Response.Headers.Add("access-control-allow-credentials", "true");
context.Response.Headers.Add("Access-Control-Allow-Origin", "*");
context.Response.Headers.Add("content-type", "application/json; charset=utf-8");
context.Response.StatusCode = 200;
await context.Response.WriteAsync(_timeError);
}
}
}
else
{
context.Response.StatusCode = 401;
await context.Response.WriteAsync("request error");
}
}
public abstract bool PathUri(HttpContext context);
}
}