.netcore2.1 使用middleware对api请求头进行验证

  本文只对api接口,header请求参数进行简单验证,起到抛砖引玉使用,需要深入验证,请自行扩展

  项目目录结构如图

  •   中间件类
using ApiMiddleware.Common.DataEnityModel;
using ApiMiddleware.Common.DbContext;
using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Primitives;
using Newtonsoft.Json;
using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ApiMiddleware.Middleware
{
    public class RequestHeaderVerificationMiddleware
    {
        private readonly RequestDelegate _next;
        private readonly ILogger _logger;

        /// <summary>
        /// 计时器
        /// </summary>
        private Stopwatch _stopwatch;
        private const string RESPONSE_HEADER_RESPONSE_TIME = "X-Response-Time-ms";

        public RequestHeaderVerificationMiddleware(RequestDelegate next, ILogger<RequestHeaderVerificationMiddleware> logger)
        {
            _next = next;
            _logger = logger;
        }

        public async Task Invoke(HttpContext context, MySqlMasterDbContext masterDbContext)
        {
            _stopwatch = new Stopwatch();
            _stopwatch.Start();
            _logger.LogError($"Handling request: {context.Request.Path}");

            if (!context.Request.Headers.TryGetValue("request_id", out StringValues request_id) || string.IsNullOrEmpty(request_id))
            {
                await HandleMessage(context, JsonConvert.SerializeObject(new { msg = "request_id不可为空", request_id = request_id }));
                goto step;
            }
            if (!context.Request.Headers.TryGetValue("uname", out StringValues uname) || string.IsNullOrEmpty(uname))
            {
                await HandleMessage(context, JsonConvert.SerializeObject(new { msg = "名称不可为空", request_id = request_id, uname = uname }));
                goto step;
            }
            var stu = new student
            {
                id = request_id,
                stu_name = uname,
                createtime = DateTime.Now,
                updatetime = DateTime.Now
            };
            var model = masterDbContext.student.FirstOrDefault(m => m.id == request_id);
            if (model == null)
                masterDbContext.Add(stu);
            else
            {
                model.stu_name = uname;
                model.updatetime = DateTime.Now;
                masterDbContext.Update(model);
            }
            masterDbContext.SaveChanges();

            context.Response.OnStarting(() =>
            {
                // Stop the timer information and calculate the time  
                _stopwatch.Stop();
                var responseTimeForCompleteRequest = _stopwatch.ElapsedMilliseconds;
                // Add the Response time information in the Response headers.  
                context.Response.Headers[RESPONSE_HEADER_RESPONSE_TIME] = responseTimeForCompleteRequest.ToString();
                return Task.CompletedTask;
            });
        step:
            if (!context.Response.HasStarted)
            {
                await _next(context);
            }
        }


        /// <summary>
        /// 错误信息或验证信息处理方法
        /// </summary>
        /// <param name="context"></param>
        /// <param name="msg"></param>
        /// <returns></returns>
        private async Task HandleMessage(HttpContext context, string msg)
        {
            context.Response.ContentType = "text/json;charset=utf-8;";
            //浏览器在开发环境显示详细错误信息,其他环境隐藏错误信息
            await context.Response.WriteAsync(msg);
        }
    }
}
using Microsoft.AspNetCore.Builder;

namespace ApiMiddleware.Middleware
{
    public static class MyMiddlewareExtensions
    {
        public static void UseMyMiddleware(this IApplicationBuilder builder)
        {
            builder.UseMiddleware<RequestHeaderVerificationMiddleware>();
        }
    }
}
  • 数据库操作类MySqlMasterDbContext
using ApiMiddleware.Common.DataEnityModel;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace ApiMiddleware.Common.DbContext
{
    public class MySqlMasterDbContext : Microsoft.EntityFrameworkCore.DbContext
    {
        private string _conn;
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!string.IsNullOrEmpty(_conn))
            {
                optionsBuilder.UseMySQL(_conn);
            }
            base.OnConfiguring(optionsBuilder);
        }
        public MySqlMasterDbContext(DbContextOptions<MySqlMasterDbContext> options) : base(options)
        {
            Database.EnsureCreated();
        }

        public MySqlMasterDbContext(string conn)
        {
            _conn = conn;
        }
        protected override void OnModelCreating(ModelBuilder builder)
        {
            base.OnModelCreating(builder);
        }



        public DbSet<student> student { get; set; }
    }
}
  • 在Startup中注册中间件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ApiMiddleware.Common.DbContext;
using ApiMiddleware.Middleware;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;

namespace ApiMiddleware
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);
            var identityConn = "Server=localhost;Database=business;Uid=root;Pwd=root;";
            services.AddDbContext<MySqlMasterDbContext>(options => options.UseMySQL(identityConn));
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
            }
            else
            {
                app.UseHsts();
            }
            app.UseMyMiddleware();//注册中间件

            app.UseHttpsRedirection();
            app.UseMvc();
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using ApiMiddleware.Common.DataEnityModel;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;

namespace ApiMiddleware.Controllers
{
    [Route("api/[controller]")]
    [ApiController]
    public class StuController : ControllerBase
    {
        [HttpPost("stuinfo")]
        public   ActionResult<string> AddStu([FromBody]StudentExternal info)
        {
            return  JsonConvert.SerializeObject(new { result="Success",Data=info.data});
        }
    }
}
  • 请求实例测试,注意请求头不要带汉字,否则报错

  • 如请求头带汉字,则报如下提示

猜你喜欢

转载自www.cnblogs.com/personblog/p/12582673.html
今日推荐