머리말
이 글은 우리가 자체 프로젝트를 개발할 때 실제로 사용하는 글입니다. 단순한 Hello World가 아닌 실용적인 응용에 더 적합하다고 볼 수 있습니다.
미들웨어의 역할
우리는 모든 웹 프레임워크가 http 요청을 파이프라인으로 캡슐화하고 각 요청이 파이프라인을 통과하여 최종적으로 코드에 도달한다는 것을 알고 있습니다. 썼다. 그런 다음 미들웨어는 요청 프로세스를 가로채고 다른 처리 및 응답을 수행하는 데 사용되는 애플리케이션 파이프라인의 구성 요소입니다. 미들웨어는 여러 개가 있을 수 있으며 각 미들웨어는 파이프라인의 요청을 가로챌 수 있으며 요청을 다음 미들웨어로 전달할지 여부를 결정할 수 있습니다.
asp.net 코어는 미들웨어를 asp.net 파이프라인 요청에 등록하기 위해 IApplicationBuilder 인터페이스를 제공합니다. 미들웨어는 일반적인 AOP 애플리케이션입니다.
각 미들웨어는 요청 전후에 동작할 수 있습니다. 요청 처리가 완료된 후 다음 요청으로 전달됩니다.
미들웨어 실행 방법
기본적으로 미들웨어의 실행 순서는 Startup.cs 파일의 public void Configure(IApplicationBuilder 앱){} 메서드에 등록된 순서를 기반으로 합니다.
파이프라인에 "미들웨어"를 등록하는 방법은 3가지 정도 있습니다
1.app.Use(), IApplicationBuilder 인터페이스가 기본적으로 제공되며 이를 사용합니다. 등록 등을 위해.
2.app.Run()은 확장 메서드입니다. Http 컨텍스트 정보가 포함된 RequestDelegate 대리자가 필요합니다. 파이프라인의 마지막 단계에서 항상 실행되기 때문에 다음 매개변수가 없습니다. .
3.app.Map()은 MVC 라우팅과 유사한 확장 방법이기도 하며 일반적으로 일부 특수 요청 경로를 처리하는 데 사용됩니다. 예: www.example.com/token 등
위의 Run 및 Map은 IApplicationBuilder 인터페이스의 확장인 Use를 내부적으로 호출합니다. 이름이 충분히 정확하지 않다고 생각되면 다음 확장 메서드가 진정한 등록 미들웨어이자 가장 좋습니다. 강력하다.
app.UseMiddlewarea8093152e673feb7aba1828c43532094() 예, 그게 전부입니다. 왜 강력하다고 하는가? 미들웨어를 등록하는 기능뿐만 아니라 앞으로 대부분의 상황에서 활용될 DI(Dependency Injection) 기능도 제공하기 때문이다.
미들웨어와 필터의 차이점
MVC 프레임워크에 익숙한 학생들은 MVC가 요청을 처리하는 데 사용할 수 있고 전후에 실행해야 하는 5가지 주요 필터도 제공한다는 것을 알아야 합니다. 암호. 이는 AuthenticationFilter, AuthorizationFilter, ActionFilter, ExceptionFilter 및 ResultFilter입니다.
설명에 따르면 미들웨어와 필터의 기능은 유사하다고 볼 수 있는데, 차이점은 무엇인가요? 또 다른 미들웨어를 구축하는 이유는 무엇입니까?
실제로 필터와 미들웨어는 초점이 다릅니다. 즉, 책임도 다르고 수행하는 작업도 다릅니다.
예를 들어 미들웨어는 아지노스의 전쟁검, 필터는 용의 분노, 타렉고사의 영혼 지팡이, 당신은 용의 분노를 들고 있는 전사, 타이 레고사의 영혼을 운반하는 지팡이는 사람을 죽이러 전장에 나갑니다. .데미지를 주기는 하지만 지팡이로 가하는 데미지는 낮고, 속성도 감소됩니다.
두 가지 AOP 도구로서 필터는 애플리케이션 자체에 더 적합합니다. 예를 들어 ActionFilter 및 ResultFilter를 보면 Action 및 ActionResult와 직접 상호 작용하는 것입니까? 매우 가깝다고 느껴지나요? 그런 다음 출력 결과의 형식을 지정하고 요청한 ViewModel의 데이터를 확인하는 등의 작업이 필요합니다. 이는 MVC의 일부이며 작업 컨텍스트에 대한 일부 정보를 가로챌 수 있지만 미들웨어에는 이러한 기능이 없습니다.
미들웨어는 언제 필요할까요?
그렇다면 미들웨어는 언제 사용해야 할까요? 제가 이해하는 바는 비즈니스와 거의 관련이 없는 파이프라인에서 수행해야 하는 일부 작업(예: 인증, 세션 저장, 로깅 등)을 우리 애플리케이션에서 사용할 수 있다는 것입니다. 실제로 asp.net 핵심 프로젝트 자체에는 이미 많은 미들웨어가 포함되어 있습니다.
예를 들어, 새로운 asp.net 핵심 애플리케이션을 생성할 때 기본 생성 템플릿 중
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory) { app.UseDeveloperExceptionPage(); app.UseStaticFiles(); loggerFactory.AddConsole(); app.UseMvc(routes => { routes.MapRoute( name: "default", template: "{controller=Home}/{action=Index}/{id?}"); }); }
은 너무 게으릅니다. 다운로드 소스 코드를 사용할 수 있습니다. Reflector를 사용하여 소스 코드를 봅니다.
//扩展方法`app.UseDeveloperExceptionPage();` public static class DeveloperExceptionPageExtensions { // Methods public static IApplicationBuilder UseDeveloperExceptionPage(this IApplicationBuilder app) { if (app == null) { throw new ArgumentNullException("app"); } return UseMiddlewareExtensions.UseMiddleware<DeveloperExceptionPageMiddleware>(app, Array.Empty<object>()); } }
//扩展方法`app.UseStaticFiles();` public static class StaticFileExtensions { // Methods public static IApplicationBuilder UseStaticFiles(this IApplicationBuilder app) { if (app == null) { throw new ArgumentNullException("app"); } return UseMiddlewareExtensions.UseMiddleware<StaticFileMiddleware>(app, Array.Empty<object>()); } }
앱을 볼 수 있습니다. .UseDeveloperExceptionPage(), app .UseStaticFiles() 등은 모두 미들웨어를 통해 구현됩니다.
나만의 미들웨어를 커스터마이즈하는 방법
배경: 우리 프로젝트에서 미들웨어를 사용하는 시나리오는 사용자(User) 정보를 다른 부서와 공유해야 한다는 것입니다. 플랫폼과 하위 시스템을 예로 들면, 우리는 사용자 정보, 로그인, 등록 및 기타 기능을 플랫폼에 배치하는 하위 시스템을 개발하고 있습니다. 이는 플랫폼이 Java 언어로 개발된 것입니다. 일부 페이지에서는 로그인 여부를 확인해야 하고, 다른 페이지에서는 로그인 여부를 확인할 필요가 없으므로 Identity 기능을 대체하기 위한 본인 확인 시스템이 필요합니다.
幸运的是微软已经给我们提供了一套身份验证的中间件,在Microsoft.AspNetCore.Authentication命名空间下,我们只需要拓展,添加自己的功能就行了 。具体怎么做呢?直接看代码吧。
根据约定俗成,中间件类需要有一个Invoke方法,签名是public async Task Invoke(HttpContext context){},下面是一个中间件的示例类:
public class RequestLoggerMiddleware { private readonly RequestDelegate _next; private readonly ILogger _logger; public RequestLoggerMiddleware(RequestDelegate next, ILoggerFactory loggerFactory) { _next = next; _logger = loggerFactory.CreateLogger<RequestLoggerMiddleware>(); } public async Task Invoke(HttpContext context) { _logger.LogInformation("Handling request: " + context.Request.Path); await _next.Invoke(context); _logger.LogInformation("Finished handling request."); } }
了解了上面的约定之后,我们就开始定义我们自己的中间件Class。
我们需要一个流程图来理清逻辑思路,以便于写代码的时候思路更加的清晰。
平台有一个要求就是,用户在我们子系统退出之后,要调用平台的一个接口通知他们,他们要做一些后续的业务。
OK,开始撸码。
首先创建一个PlatformAuthoricationMiddleware,它继承于Microsoft.AspNetCore.Authentication下的类AuthenticationMiddleware,由于AuthenticationMiddleware已经实现了Invoke功能,所以我们只需要重写(override)它里面的一些方法就可以了。等等,我们好像还需要一些配置,比如流程图中的ReturnUrl,平台的Cookie的Key值,平台验证用户合法性的接口地址等参数。
建立一个Options类进行配置的设置,我们取名字为:PlatformAuthenticationOptions,继承AuthenticationOptions,并且实现掉IOptions8742468051c85b06f0a0af9e3e506b5c接口,这样子就能在Startup中直接配置了。
我们只需要重写AuthenticationMiddleware中的CreateHandler方法就行了,在Handler中可以实现掉我们中间件的功能。
然后创建一个处理的Handler类,取名为PlatformAuthenticationHandler,继承于AuthenticationHandler58fec2039d3938dc329cad313e09b70a用来处理请求中的调用。
至此,我们的核心需要的类已经建立完了,剩下的就是填充代码。
1.在PlatformAuthenticationHandler中重写HandleAuthenticateAsync()方法 , 进行主流程的控制。
2.在PlatformAuthenticationHandler中重写FinishResponseAsync()方法,进行Session的存储操作。
3.在PlatformAuthenticationHandler中重写HandleSignOutAsync()方法,进行登出的控制,因为用户登出之后我们要通知平台做一些其他操作。
4.在PlatformAuthenticationHandler中重写HandleUnauthorizedAsync()方法,进行未认证操作。
最后,我们需要一个扩展类来把我们的中间件以扩展方法注册到管道当中去 。
public static class MiddlewareExtensions { public static IApplicationBuilder UsePlatformAuthentication(this IApplicationBuilder app) { if (app == null) { throw new ArgumentNullException(nameof(app)); } return app.UseMiddleware<PlatformAuthenticationMiddleware>(); } public static IApplicationBuilder UsePlatformAuthentication(this IApplicationBuilder app, CookieAuthenticationOptions options) { if (app == null) { throw new ArgumentNullException(nameof(app)); } if (options == null) { throw new ArgumentNullException(nameof(options)); } return app.UseMiddleware<PlatformAuthenticationMiddleware>(Options.Create(options)); } }
在Startup中就是app.UsePlatformAuthentication()
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) { loggerFactory.AddConsole(Configuration.GetSection("Logging")); //注册PlatformAuthentication中间件 app.UsePlatformAuthentication(new PlatformAuthenticationOptions() { UserSessionStore = new UserSessionStore(), }); app.UseMvc(); }
现在,我们的中间件核心业务流程的实现已经出来了,我就不大篇幅的粘贴代码了,会影响阅读,感兴趣具体实现的朋友可以去下面的地址查看代码,有具体流程的注释。
以上就是本文的全部内容,希望对大家的学习有所帮助,更多浅谈ASP.NET Core 中间件详解及项目实战相关文章请关注PHP中文网!