ASP.NET 코어 미들웨어 상세 설명 및 프로젝트 실전

머리말
이 글 은 우리 가 자신의 프로젝트 를 개발 하 는 데 실제 적 으로 사용 한 것 으로 실제 응용 에 비교적 적합 하 며 중간 부품 에 대한 깊이 있 는 사용 이 라 고 할 수 있 습 니 다.간단 한 Hello World 가 아 닙 니 다.
중간 부품(Middleware)의 역할
모든 웹 프레임 워 크 는 http 요청 을 하나의 파이프 로 밀봉 하고 모든 요청 은 파이프 의 일련의 작업 을 거 쳐 우리 가 쓴 코드 에 도착 한 다 는 것 을 알 고 있 습 니 다.그러면 중간 부품 은 응용 프로그램 파이프 에 있 는 구성 요소 로 요청 과정 을 차단 하고 다른 처리 와 응답 을 하 는 데 사 용 됩 니 다.미들웨어 는 여러 개가 있 을 수 있 습 니 다.모든 미들웨어 는 파이프 의 요청 을 차단 할 수 있 습 니 다.요청 을 다음 미들웨어 로 옮 길 지 여 부 를 결정 할 수 있 습 니 다.
asp.net core 는 IApplicationBuilder 인 터 페 이 스 를 제공 하여 미들웨어 를 asp.net 의 파이프 요청 에 등록 시 켰 습 니 다.미들웨어 는 전형 적 인 AOP 응용 입 니 다.
모든 미들웨어 는 요청 하기 전과 그 후에 조작 할 수 있다.요청 처리 가 완료 되면 다음 요청 에 전달 합 니 다.
중간 부품 의 운행 방식
기본 적 인 상황 에서 중간 부품 의 집행 순 서 는Startup.cs파일 에서public void Configure(IApplicationBuilder app){} 방법 에 등 록 된 선후 순서에 따라 집행 된다.
대략 세 가지 방식 으로 파이프 에'중간 부품'을 등록 할 수 있다
1.app.Use(),IApplicationBuilder인터페이스 원생 제공,등록 등 을 모두 사용한다.
2.app.Run()확장 방법 입 니 다.RequestDelegate의뢰 가 필요 합 니 다.Http 의 컨 텍스트 정 보 를 포함 하고 next 인자 가 없습니다.항상 파이프 의 마지막 단계 에서 실행 되 기 때 문 입 니 다.
3.app.Map()또한 확장 방법 으로 MVC 와 유사 한 경로 이 고 용 도 는 보통 특수 요청 경로 의 처리 이다.예 를 들 어www.example.com/token등.
위의 Run,Map 내부 도 호출 된 Use 입 니 다.IApplicationBuilder 인터페이스 확장 이 라 고 할 수 있 습 니 다.이름 이 정확 하지 않다 고 생각하면 다음 확장 방법 은 정통 등록 미들웨어 이자 기능 이 가장 강 합 니 다.app.UseMiddleware<>()맞아요.바로 이거 예요.왜 기능 이 강하 다 고 하 죠?중간 부품 을 등록 하 는 기능 뿐만 아니 라 주입(DI)에 의존 하 는 기능 도 제공 해 이후 대부분의 경우 이 를 사용 하기 때문이다.
미들웨어(Middleware)와 필터(Filter)의 차이
MVC 프레임 워 크 를 잘 아 는 학생 들 은 MVC 도 요청 전후 에 실행 해 야 할 코드 를 처리 할 수 있 도록 5 대 필 터 를 제공 했다 는 것 을 알 아야 한다.각각AuthenticationFilter,AuthorizationFilter,ActionFilter,ExceptionFilter,ResultFilter이다.
설명 에 따 르 면 미들웨어 와 필터 의 기능 이 유사 하 다 는 것 을 알 수 있다.그러면 그들 은 어떤 차이 가 있 습 니까?왜 또 중간 부품 을 만 들 려 고 합 니까?
 사실 필터 와 미들웨어 의 관심 사 는 다르다.즉,직책 이 다 르 고 하 는 일이 다르다 는 것 이다.
밤 을 들 어 보 세 요.중간 부품 은 에 신 노 스 전투 칼날 같 습 니 다.필 터 는 거 룡 의 분노 같 습 니 다.테 레 구 샤 의 기 혼 장 입 니 다.당신 의 한 전사 가 거 룡 의 분 노 를 들 고 테 레 구 샤 의 기 혼 장 을 들 고 전쟁터 에 나 가 사람 을 죽 였 습 니 다.모두 상 처 를 입 었 지만 지팡이 를 들 고 상 처 를 낮 추 었 습 니 다.말 하지 않 아 도 소속 성 을 줄 였 습 니 다.
같은 두 개의 AOP 이기 로 서 필 터 는 업무 에 더욱 적합 합 니 다.이것 은 응용 프로그램 자체 에 관심 을 가지 고 있 습 니 다.예 를 들 어 Action Filter 와 ResultFilter 를 보면 모두 당신 의 Action,Action Result 와 직접 상호작용 을 했 습 니 다.당신 과 가 까 운 느낌 이 들 지 않 습 니까?그러면 저 는 제 출력 결 과 를 포맷 하고 제 가 요청 한 ViewModel 에 대해 데이터 검증 을 했 습 니 다.필 터 를 쓰 는 게 틀림 없어.이것 은 MVC 의 일부분 입 니 다.Action 컨 텍스트 의 일부 정 보 를 차단 할 수 있 고 미들웨어 는 이 능력 이 없습니다.
무슨 상황 이 야?
그렇다면 미들웨어 는 언제 사용 하나 요?제 이 해 는 저희 응용 프로그램 에서 업무 관계 가 크 지 않 은 파이프 에서 해 야 할 일 들 을 사용 할 수 있다 는 것 입 니 다.예 를 들 어 인증,Session 저장,로그 기록 등 입 니 다.사실 우리 의 asp.net core 프로젝트 자체 에는 이미 많은 미들웨어 가 포함 되 어 있다.
예 를 들 어,asp.net core 프로그램 을 새로 만 들 때 기본 으로 생 성 된 템 플 릿 에서

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>());
  }
}

app.UseDeveloperExceptionPage(),app.UseStaticFiles()등 은 모두 중간 부품 을 통 해 이 루어 진 것 을 볼 수 있다.
어떻게 자신의 미들웨어 를 사용자 정의 합 니까?
배경:저희 프로젝트 가 미들웨어 에 사용 되 는 상황 은 다른 부서 와 사용자(User)정 보 를 공유 해 야 한 다 는 것 입 니 다.플랫폼 과 서브 시스템 을 예 로 들 어 저 희 는 서브 시스템 을 개발 하고 있 습 니 다.그 중에서 사용자 정보,로그 인,등록 등 기능 은 플랫폼 에 놓 여 있 습 니 다.이것 은 다 중 언어 를 뛰 어 넘 는 시스템 입 니 다.플랫폼 은 자바 언어 개발 입 니 다.사용자 가 서브 시스템 의 일부 페이지 를 방문 할 때 로그 인 여 부 를 검증 해 야 합 니 다.다른 일부 페이지 는 로그 인 여 부 를 검증 할 필요 가 없습니다.그래서 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 기능 을 실 현 했 기 때문에 우 리 는 그 안의 몇 가지 방법 만 다시 쓰 면 됩 니 다.등등,우 리 는 프로 세 스 맵 의 ReturnUrl,플랫폼 의 Cookie 의 Key 값,플랫폼 이 사용자 의 합 법성 을 검증 하 는 인터페이스 주소 등 인 자 를 설정 해 야 할 것 같 습 니 다.
  • 하나의Options클래스 를 설정 합 니 다.우 리 는 이름 을PlatformAuthenticationOptions,계승AuthenticationOptions,그리고IOptions<T>인 터 페 이 스 를 실현 하면 Startup 에서 직접 설정 할 수 있 습 니 다.
  • 우 리 는AuthenticationMiddleware중의CreateHandler방법 만 다시 쓰 면 된다.Handler 에서 우리 중간 부품 을 떨 어 뜨리 는 기능 을 실현 할 수 있다.
  • 그리고 처 리 된 Handler 클래스 를 만 들 고PlatformAuthenticationHandler이름 을 지어AuthenticationHandler<TOptions>요청 의 호출 을 처리 합 니 다.
  • 이로써 우리 의 핵심 에 필요 한 클래스 는 이미 만 들 어 졌 고 나머지 는 코드 를 채 우 는 것 이다.
    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();
    }
    
    
    현재 우리 의 중간 부품 핵심 업무 절차 의 실현 이 이미 나 왔 습 니 다.저 는 편폭 이 크 지 않 은 붙 여 넣 기 코드 를 읽 는 데 영향 을 줄 수 있 습 니 다.구체 적 으로 실현 하 는 것 에 관심 이 있 는 친 구 는 아래 주소 로 코드 를 볼 수 있 고 구체 적 인 절차 에 대한 설명 이 있 습 니 다.
    예제 소스 코드:demo
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기