ASP.NET Core 入門教程 九、ASP.NET Core 中間件(Middleware)入門

1、前言

一、本教程主要內容

  • ASP.NET Core 中間件介紹
  • 經過自定義 ASP.NET Core 中間件實現請求驗籤

二、本教程環境信息

軟件/環境 說明
操做系統 Windows 10
SDK 2.1.401
ASP.NET Core 2.1.3
MySQL 8.0.x
IDE Visual Studio Code 1.32.3
瀏覽器 Chrome 70
VS Code插件 版本 說明
C# 1.17.1 提供C#智能感知, .NET Core 調試、編譯等
vscdoe-solution-explorer 0.3.1 提供解決方案視圖

本篇代碼如下代碼進行調整:https://github.com/ken-io/asp...html

三、前置知識

可能須要的前置知識git

  • C# 委託(Delegate)

http://www.runoob.com/csharp/...github

  • C# 擴展方法

https://docs.microsoft.com/zh...api

2、ASP.NET Core 中間件介紹

一、ASP.NET Core 中間件基本說明

當 ASP.NET Core MVC應用從Kestrel接收到請求,會創建HttpContext並交由Application來處理請求。在Application中會有一個處理該請求的通道,這就是ASP.NET Core 管道,一般稱之爲:請求處理管道瀏覽器

在這個管道中,有一系列有序處理請求的組件,就是中間件(Middleware)。安全

image

圖中藍色的部分能夠認爲是系統內置比較靠前的中間件或者咱們自定義的中間件,MVC是一個特殊的中間件且一般放在最後,因此這裏單獨畫出來服務器

對於MVC中間件,若是請求的URL與路由匹配,那麼後面的中間件均不會生效。因此MVC一般放在最後。

ASP.NET Core中會內置一些中間件,例如:身份驗證、靜態文件處理、MVC等。每一箇中間件在接受到請求後均可以選擇是交由下一個中間件處理仍是直接返回結果。例如:app

  • 身份驗證中間件驗證未經過會直接引導到登錄頁
  • 靜態文件中間件判斷爲靜態文件就會直接返回靜態文件內容

因此,中間件能夠理解爲請求處理管道中的請求處理器。咱們也能夠經過自定義中間件註冊到管道中來干預請求。asp.net

二、ASP.NET Core 中間件基礎使用

在程序中,中間件是基於委託來構建的。在應用啓動時經過IApplicationBuilder註冊到通道中。ide

具體見啓動類Startup.cs

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    if (env.IsDevelopment())
    {
        app.UseDeveloperExceptionPage();
    }

    app.UseMvc(routes =>
    {
        //配置默認路由
        routes.MapRoute(
            name: "Default",
            template: "{controller}/{action}",
            defaults: new { controller = "Home", action = "Index" }
        );
    });
}

UseDeveloperExceptionPageUseMvc都是接口IApplicationBuilder的擴展方法。

3、使用 ASP.NET Core 中間件實現請求驗籤

若是你開發的API是爲手機App服務的,那麼你的API是必定要暴露給公網的,若是有人拿到API地址進行非法請求,獲取用戶信息或者是篡改數據,用戶隱私、數據就會受到損害。這是很不安全的,咱們可讓客戶端請求的時候必須攜帶簽名,在服務器端鑑權(驗證簽名)經過了再放行,這樣就安全不少了。

一、建立驗籤中間件

在項目Ken.Tutorial.Web建立目錄Middlewares,而後建立類:TokenCheckMiddleware.cs

using System;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Http;

namespace Ken.Tutorial.Web.Middlewares
{
    public class TokenCheckMiddleware
    {
        private readonly RequestDelegate _next;
        public TokenCheckMiddleware(RequestDelegate requestDelegate)
        {
            this._next = requestDelegate;
        }

        public Task Invoke(HttpContext context)
        {
            //先從Url取token,若是取不到就從Form表單中取token
            var token = context.Request.Query["token"].ToString() ?? context.Request.Form["token"].ToString();
            if (string.IsNullOrWhiteSpace(token))
            {
                //若是沒有獲取到token信息,那麼久返回token missing
                return context.Response.WriteAsync("token missing");
            }
            //獲取前1分鐘和當前的分鐘
            var minute0 = DateTime.Now.AddMinutes(-1).ToString("yyyy-MM-dd HH:mm");
            var minute = DateTime.Now.ToString("yyyy-MM-dd HH:mm");
            //當token和前一分鐘或當前分鐘任一時間字符串的MD5哈希一致,就認爲是合法請求
            if (token == MD5Hash(minute) || token == MD5Hash(minute0))
            {
                return _next.Invoke(context);
            }
            //若是token未驗證經過返回token error
            return context.Response.WriteAsync("token error");
        }

        public string MD5Hash(string value)
        {
            using (var md5 = MD5.Create())
            {
                var result = md5.ComputeHash(Encoding.ASCII.GetBytes(value));
                var strResult = BitConverter.ToString(result);
                return strResult.Replace("-", "");
            }
        }
    }
}

因爲是側重自定義中間件,全部驗籤的邏輯就寫的很是簡單,若是實際項目使用,能夠按照本身需求調整

二、建立擴展方法

Middlewares目錄下新建類:MiddlewareExtension.cs

using Microsoft.AspNetCore.Builder;

namespace Ken.Tutorial.Web.Middlewares
{
    public static class MiddlewareExtension
    {
        public static IApplicationBuilder UseTokenCheck(this IApplicationBuilder builder)
        {
            return builder.UseMiddleware<TokenCheckMiddleware>();
        }
    }
}

這裏咱們經過擴展方法,將TokenCheckMiddleware掛在接口IApplicationBuilder

三、中間件註冊/引用

在啓動類Startup.csConfigure方法中註冊/引用中間件

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    
    //省略部分代碼

    app.UseTokenCheck();
    
    app.UseMvc(routes =>
    {
        //省略路由配置代碼
    });
}

若是你以爲擴展方法有點多餘,也能夠直接使用UseMiddleware方法註冊

public void Configure(IApplicationBuilder app, IHostingEnvironment env)
{
    
    //省略部分代碼

    app.UseMiddleware<TokenCheckMiddleware>();
    
    app.UseMvc(routes =>
    {
        //省略路由配置代碼
    });
}

這裏要注意的是,若是你是一個MVC應用,請必定要把MVC這個中間件做爲最後一個註冊。由於中間件是按照註冊順序被調用的。若是放在MVC以後,請求的URL也有對應路由適配,那麼整個請求已經被MVC接管。後面的中間件就不會被調用了。

四、驗籤中間件測試

啓動應用,而後驗證不一樣狀況下的訪問結果

URL Response
localhost:5001 token missing
localhost:5001?token=test token error
localhost:5001?token=3D76FEA1D0ADD0C7639B73023436C6EA Hello World ! -ken.io

爲了方便測試,MD5哈希的值咱們能夠在線生成:ttp://tool.chinaz.com/tools/md5.aspx

把當前分鐘,例如:2019-03-27 23:23 經過MD5在線生成那就是3D76FEA1D0ADD0C7639B73023436C6EA

4、備註

  • 本文代碼示例

https://github.com/ken-io/asp...

  • 本文參考

https://docs.microsoft.com/zh...

  • 延伸閱讀

https://www.cnblogs.com/artec...


本文首發於個人獨立博客:https://ken.io/note/asp.net-c...

相關文章
相關標籤/搜索