软件/环境 | 说明 |
---|---|
操做系统 | 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
http://www.runoob.com/csharp/...github
https://docs.microsoft.com/zh...api
当 ASP.NET Core MVC应用从Kestrel接收到请求,会创建HttpContext并交由Application来处理请求。在Application中会有一个处理该请求的通道,这就是ASP.NET Core 管道,一般称之为:请求处理管道浏览器
在这个管道中,有一系列有序处理请求的组件,就是中间件(Middleware)。安全
图中蓝色的部分能够认为是系统内置比较靠前的中间件或者咱们自定义的中间件,MVC是一个特殊的中间件且一般放在最后,因此这里单独画出来服务器
对于MVC中间件,若是请求的URL与路由匹配,那么后面的中间件均不会生效。因此MVC一般放在最后。
ASP.NET Core中会内置一些中间件,例如:身份验证、静态文件处理、MVC等。每一个中间件在接受到请求后均可以选择是交由下一个中间件处理仍是直接返回结果。例如:app
因此,中间件能够理解为请求处理管道中的请求处理器。咱们也能够经过自定义中间件注册到管道中来干预请求。asp.net
在程序中,中间件是基于委托来构建的。在应用启动时经过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" } ); }); }
UseDeveloperExceptionPage
、UseMvc
都是接口IApplicationBuilder
的扩展方法。
若是你开发的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.cs
的Configure
方法中注册/引用中间件
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
https://github.com/ken-io/asp...
https://docs.microsoft.com/zh...
https://www.cnblogs.com/artec...
本文首发于个人独立博客:https://ken.io/note/asp.net-c...