DotNet Core WebApi项目搭建

06-01 1204阅读

DotNet Core WebApi项目搭建

环境搭建

Core执行过程

DotNet Core WebApi项目搭建

IIS发布

https://dotnet.microsoft.com/download/

1 需要安装运行时和托管拥绑包

地址:https://dotnet.microsoft.com/download/dotnetcore/thank-you/runtime-aspnetcore-3.1.2-windows-hosting-bundle-installer

2 必须要发布不能直接执行系统的根目录

3 需要安装Core的运行时环境

4 指定为无代码托管

  • 确认启用了WWW服务

    DotNet Core WebApi项目搭建

  • 配置Core的运行时环境,在IIS的模块中添加AspNetCoreModuleV2

    DotNet Core WebApi项目搭建

  • 设置无托代码(Core最新版本可以不设)

    DotNet Core WebApi项目搭建

    WebApi启动方式

    • WebApi启动方式,使用CMD切换到DLL文件目录下通过命令可以运行WebApi
      dotnet Test.CoreWebApi.dll --urls="http://*:8004"--ip="127.0.0.1"--port= 8004
      

      配置Swagger

      CoreWebApi-Swagger配置

      1.nuget安装:Swashbuckle.AspNetCore程序包;

      2.注册Swagger服务;

      3.在中间件中使用Swagger;

      • 在Startup.cs类中注册Swagger服务并增加中间件

        using System;
        using System.Collections.Generic;
        using System.Linq;
        using System.Threading.Tasks;
        using Microsoft.AspNetCore.Builder;
        using Microsoft.AspNetCore.Hosting;
        using Microsoft.AspNetCore.Mvc;
        using Microsoft.Extensions.Configuration;
        using Microsoft.Extensions.DependencyInjection;
        using Microsoft.Extensions.Hosting;
        using Microsoft.Extensions.Logging;
        using Microsoft.OpenApi.Models;
        namespace Test.Core.WebApi
        {
            /// 
            /// Core 项目中导出都是IOC + DI
            /// 
            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)
                {
                    #region 注册Swagger服务 
                    services.AddSwaggerGen(s =>
                    {
                        //注册 Swagger
                        s.SwaggerDoc("V1", new OpenApiInfo()
                        {
                            Title = "test",//显示名称
                            Version = "version-01",//显示版本
                            Description = "朝夕教育Api学习"//显示标题
                        });
                    });
                    #endregion
                    services.AddControllers();
                }
                // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
                public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
                {
                    if (env.IsDevelopment())
                    {
                        app.UseDeveloperExceptionPage();
                    } 
                    //使用Swagger中间件
                    app.UseSwagger();
                    app.UseSwaggerUI(s =>
                    {
                        s.SwaggerEndpoint("/swagger/V1/swagger.json", "test1");//不同版本的文件,test1与文件名对应可以进行切换。
                    });
                    //使用中间件
                    app.UseRouting();
                    app.UseAuthorization();          
                    app.UseEndpoints(endpoints =>
                    {
                        endpoints.MapControllers();
                    });
                }
            }
        }
        
      • 访问路径:localhost:XXXX/swagger/index.html 注意大小写

      • 在launchSettings.json文件中修改起始页面

        {
          "$schema": "http://json.schemastore.org/launchsettings.json",
          "iisSettings": {
            "windowsAuthentication": false,
            "anonymousAuthentication": true,
            "iisExpress": {
              "applicationUrl": "http://localhost:50786",
              "sslPort": 0
            }
          },
          "profiles": {
            "IIS Express": {
              "commandName": "IISExpress",
              "launchBrowser": true,
              "launchUrl": "swagger/index.html",//设置Swagger为初始页面
              "environmentVariables": {
                "ASPNETCORE_ENVIRONMENT": "Development"
              }
            },
            "Test.Core.WebApi": {
              "commandName": "Project",
              "launchBrowser": true,
              "launchUrl": "weatherforecast",
              "applicationUrl": "http://localhost:5000",
              "environmentVariables": {
                "ASPNETCORE_ENVIRONMENT": "Development"
              }
            }
          }
        }
        

        Nginx负载均衡

        DotNet Core WebApi项目搭建

        Nginx环境

        1.下载Nginx安装包:http://nginx.org/en/download.html

        2.启动Nginx服务器;建议下载稳定版;

        3.可以查看任务管理器;会出现Nginx进程

        Nginx配置负载均衡

        listen 9090; #设计Nginx的默认端口
        server_name 9090.max.com;#注释:这里转发的设置
        location /{
        	#root html;
        	#index index.html index.htm;
        	proxypass http://webApi;//设置代理转发;转发到服务器列表
        }
        服务器列表:
        upstream webApi {
        	server localhost:8001;
        	server localhost:8002;
        	server localhost:8003;
        
        • Nginx配置文件内容~\nginx-1.16.1\conf\nginx.conf

          #user  nobody;
          worker_processes  1;
          #error_log  logs/error.log;
          #error_log  logs/error.log  notice;
          #error_log  logs/error.log  info;
          #pid        logs/nginx.pid;
          events {
              worker_connections  1024;
          }
          http {
              include       mime.types;
              default_type  application/octet-stream;
              #log_format  main  '$remote_addr - $remote_user [$time_local] "$request" '
              #                  '$status $body_bytes_sent "$http_referer" '
              #                  '"$http_user_agent" "$http_x_forwarded_for"';
              #access_log  logs/access.log  main;
              sendfile        on;
              #tcp_nopush     on;
              #keepalive_timeout  0;
              keepalive_timeout  65;
              #gzip  on;
              
          	#注释:这里转发的设置
              upstream webApi {
          	server localhost:8001;
          	server localhost:8002;
          	server localhost:8003;
               }
              server {
                  listen       9090;
                  server_name  9090.max.com;#注释:这里转发的设置
                  #charset koi8-r;
                  #access_log  logs/host.access.log  main;
                  location / {
                        proxy_pass http://webApi; #注释:这里转发的设置
                  }
                  #error_page  404              /404.html;
                  # redirect server error pages to the static page /50x.html
                  #
                  error_page   500 502 503 504  /50x.html;
                  location = /50x.html {
                      root   html;
                  }
                  # proxy the PHP scripts to Apache listening on 127.0.0.1:80
                  #
                  #location ~ \.php$ {
                  #    proxy_pass   http://127.0.0.1;
                  #}
                  # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
                  #
                  #location ~ \.php$ {
                  #    root           html;
                  #    fastcgi_pass   127.0.0.1:9000;
                  #    fastcgi_index  index.php;
                  #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
                  #    include        fastcgi_params;
                  #}
                  # deny access to .htaccess files, if Apache's document root
                  # concurs with nginx's one
                  #
                  #location ~ /\.ht {
                  #    deny  all;
                  #}
              }
              # another virtual host using mix of IP-, name-, and port-based configuration
              #
              #server {
              #    listen       8000;
              #    listen       somename:8080;
              #    server_name  somename  alias  another.alias;
              #    location / {
              #        root   html;
              #        index  index.html index.htm;
              #    }
              #}
              # HTTPS server
              #
              #server {
              #    listen       443 ssl;
              #    server_name  localhost;
              #    ssl_certificate      cert.pem;
              #    ssl_certificate_key  cert.key;
              #    ssl_session_cache    shared:SSL:1m;
              #    ssl_session_timeout  5m;
              #    ssl_ciphers  HIGH:!aNULL:!MD5;
              #    ssl_prefer_server_ciphers  on;
              #    location / {
              #        root   html;
              #        index  index.html index.htm;
              #    }
              #}
          }
          

          Log4Net集成

          1.Nuget引入log4net/ Microsoft.Extensions.Logging.Log4Net.AspNetCore

          2.增加配置log4net配置文件

          3.使用配置文件

          logging.AddFilter("System", LogLevel.Warning);
          logging.AddFilter("Microsoft", LogLevel. Warning);
          logging.AddLog4Net("ConfigFile/log4net.Config”);
          
          • Log4Net的配置文件(log4net.Config),配置文件需要设置为始终复制,否则发布后无法找到。

            
            	
            	
            		
            		
            		
            		
            		
            		
            		
            		
            		
            		
            		
            		
            		
            		
            		
            		
            		
            		
            		
            		
            			
            			
            		 
            		
            		
            		
            			
            		
            	 
            	
            	
            		
            		
            		
            	
            
            
          • 在Program.cs中进行注册

            using System;
            using System.Collections.Generic;
            using System.Linq;
            using System.Threading.Tasks;
            using Microsoft.AspNetCore.Hosting;
            using Microsoft.Extensions.Configuration;
            using Microsoft.Extensions.Hosting;
            using Microsoft.Extensions.Logging;
            namespace Test.Core.WebApi
            {
                public class Program
                {
                    public static void Main(string[] args)
                    {
                        CreateHostBuilder(args).Build().Run();
                    }
                    /// 
                    /// Builder标准的建造者模式
                    /// 
                    /// 
                    /// 
                    public static IHostBuilder CreateHostBuilder(string[] args)
                    {
                        return Host.CreateDefaultBuilder(args)
                            //Log4net注册
                        .ConfigureLogging(logging => //支持IOC  控制反转
                        {
                            logging.AddFilter("System", LogLevel.Warning);
                            logging.AddFilter("Microsoft", LogLevel.Warning);
                            logging.AddLog4Net();//配置文件默认在根目录下,如果不在此目录下应使用重载方法
                        })
                        .ConfigureWebHostDefaults(webBuilder =>
                        {
                            webBuilder.UseStartup();
                        });
                    }
                }
            }
            
          • 将Logger对象注入至控制器中进行调用

            using System;
            using System.Collections.Generic;
            using System.Linq;
            using System.Threading.Tasks;
            using Microsoft.AspNetCore.Http;
            using Microsoft.AspNetCore.Mvc;
            using Microsoft.Extensions.Logging;
            namespace Test.Core.WebApi.Controllers
            {
                [Route("api/[controller]")]
                [ApiController]
                public class SecondController : ControllerBase
                {
                    private ILogger _Logger = null;
                    public SecondController(ILogger logger)
                    {
                        this._Logger = logger;
                        _Logger.LogInformation("SecondController 被构造。。。。");
                    }
                    [Route("Get")]
                    [HttpGet]
                    public string Get()
                    {
                        _Logger.LogInformation("SecondController.Get 被调用");
                        return "this is Test--003";
                    }
                }
            }
            

            AOP-Filter

            AOP(面向切面编程)

            DotNet Core WebApi项目搭建

            IResoureFilter做缓存例子

            AOP在Core中通过Filter来实现,Core-Filter VS Asp.Net-Filter

            Asp.Net WebApiCore WehApi
            授权过滤器IAuthorizationFilter授权过滤器AuthorizeAttribute
            异常过滤器lExceptionFilter异常过滤器lExceptionFilter, lAsyncExceptionFilter
            方法过滤器lActionFilter方法过滤器ActionFilterAttribute, lActionFilter, lAsyncActionFilter
            资源过滤器lResourceFilter
            结果过滤器ResultFilterAttribute, IResultFilter, lAsyncResultFilter
            • Asp.net的Filter是在控制器实例化以后调用的。NetCoreWeiApi中的IResourceFilter是在控制器对象创建前先执行了OnResourceExecuting方法,在控制器返回数据时又执行OnResourceExecuted方法,适合做缓存使用。

              DotNet Core WebApi项目搭建

              以下是IResourceFilter做缓存应用的示例代码

              using Microsoft.AspNetCore.Mvc;
              using Microsoft.AspNetCore.Mvc.Filters;
              using System;
              using System.Collections.Generic;
              using System.Linq;
              using System.Threading.Tasks;
              namespace Test.Core.WebApi.Utility
              {
                  public class CustomResourceFilterAttribute : Attribute, IResourceFilter
                  {
                      private static Dictionary dictionaryCache = new Dictionary();
                      public void OnResourceExecuting(ResourceExecutingContext context)
                      {
                          string key = context.HttpContext.Request.Path.ToString();
                          if (dictionaryCache.ContainsKey(key))
                          {
                              context.Result = dictionaryCache[key] as ObjectResult;    //Result 短路器
                          } 
                      }
                      public void OnResourceExecuted(ResourceExecutedContext context)//当Api的数据发生了变化时应将缓存清除
                      {
                          ///把数据存储缓存;
                          //Key---path;
                          string key = context.HttpContext.Request.Path.ToString();
                          ObjectResult objectResult = context.Result as ObjectResult;
                          dictionaryCache[key] = objectResult;         
                      }
                  }
              }
              

              IActionFilter做日志的例子(搭配Log4Net)

              • 创建特性类继承于Attrbute并实现IActionFilter接口

              • 将Logger对象依赖注入到特性类中

                using Microsoft.AspNetCore.Mvc;
                using Microsoft.AspNetCore.Mvc.Filters;
                using Microsoft.Extensions.Logging;
                using System;
                using System.Collections.Generic;
                using System.Linq;
                using System.Threading.Tasks;
                namespace Test.Core.WebApi.Utility
                {
                    public class CustomActionFilterAttribute : Attribute, IActionFilter //ActionFilterAttribute //IActionFilter,//IAsyncActionFilter
                    {
                        private ILogger _Logger = null;
                		//依赖注入logger
                        public CustomActionFilterAttribute(ILogger logger)
                        {
                            _Logger = logger;
                        } 
                        /// 
                        /// 方法执行后
                        /// 
                        /// 
                        public void OnActionExecuted(ActionExecutedContext context)
                        {  
                            var result = context.Result;
                            ObjectResult objectResult= result as ObjectResult; 
                            var resultLog = $"{DateTime.Now} 调用 {context.RouteData.Values["action"]} api 完成;执行结果:{Newtonsoft.Json.JsonConvert.SerializeObject(objectResult.Value)}"; 
                            _Logger.LogInformation(resultLog); 
                        }
                        /// 
                        /// 方法执行前
                        /// 
                        /// 
                        public void OnActionExecuting(ActionExecutingContext context)
                        { 
                            var actionLog = $"{DateTime.Now} 开始调用 {context.RouteData.Values["action"]} api;参数为:{Newtonsoft.Json.JsonConvert.SerializeObject(context.ActionArguments)}"; 
                            _Logger.LogInformation(actionLog);
                            //这里就可以把信息写入到日志中来;       
                        }
                    }
                }
                
              • 特性注册方法(注意看代码注释)

                using System;
                using System.Collections.Generic;
                using System.Linq;
                using System.Threading.Tasks;
                using Microsoft.AspNetCore.Http;
                using Microsoft.AspNetCore.Mvc;
                using Test.Core.WebApi.Utility;
                namespace Test.Core.WebApi.Controllers
                {
                    //能不能注册以后让所有的Api 都生效?
                    //Startup.cs中进行注册
                    [Route("api/[controller]")]
                    [ApiController]
                    //2.Filter对控制器下的所有Api生效
                    //[ServiceFilter(typeof(CustomActionFilterAttribute))] //需要注册服务
                    [ServiceFilter(typeof(CustomControllerActionFilterAttribute))]
                    public class FilterController : ControllerBase
                    {
                        public FilterController()
                        {
                            Console.WriteLine("FilterController 被构造。。。");
                        }    
                        //难道每个方法都需要去注册一下吗?
                        //1.Filter方法注册  
                        [Route("GetInfoByParamter")]
                        [HttpGet]
                        [CustomActionFilter] //特性的方式标记  只能支持带无参数构造函数的
                        [TypeFilter(typeof(CustomActionFilterAttribute))]//不需要注册服务
                        [ServiceFilter(typeof(CustomActionFilterAttribute))] //需要注册服务
                        [CustomIOCFilterFactory(typeof(CustomActionFilterAttribute))]  //需要注册服务  
                        public string GetInfoByParamter(int id,string Name)
                        {
                            return $"this is Id={id},Name={Name}";
                        }
                    }
                }
                
              • 注册服务Startup.cs

                       // This method gets called by the runtime. Use this method to add services to the container.
                        public void ConfigureServices(IServiceCollection services)
                        {
                            #region 注册Swagger服务 
                            services.AddSwaggerGen(s =>
                            {
                                #region 注册 Swagger
                                s.SwaggerDoc("V1", new OpenApiInfo()
                                {
                                    Title = "test",
                                    Version = "version-01",
                                    Description = "朝夕教育Api学习"
                                });
                                #endregion 
                            });
                            #endregion           
                            services.AddControllers();
                            //注册服务,将类放在IOC容器中
                            services.AddSingleton();
                            services.AddSingleton();
                            services.AddSingleton();
                            #region 全局注册Filter
                            //3.对所有的方法都生效        
                            services.AddMvc(option => {
                                option.Filters.Add(typeof(CustomGlobalActionFilterAttribute));
                            });
                            #endregion
                        }
                
              • 自定义IOC工厂类CustomIOCFilterFactory的代码

                using Microsoft.AspNetCore.Mvc.Filters;
                using System;
                using System.Collections.Generic;
                using System.Linq;
                using System.Threading.Tasks;
                namespace Test.Core.WebApi.Utility
                {
                    public class CustomIOCFilterFactoryAttribute : Attribute, IFilterFactory
                    {
                        private Type _FilterType = null;
                        public CustomIOCFilterFactoryAttribute(Type type)
                        {
                            _FilterType = type;
                        }
                        public bool IsReusable => true;
                        /// 
                        /// 在Core 中对象的创建 都是通过IOC 容器来创建
                        /// 
                        /// 
                        /// 
                        public IFilterMetadata CreateInstance(IServiceProvider serviceProvider)
                        {
                            return (IFilterMetadata)serviceProvider.GetService(this._FilterType);
                        }
                    }
                }
                

                鉴权JWT

                鉴权方式

                传统的Seesion-Cookie方式

                DotNet Core WebApi项目搭建

                基于Token的无状态方式

                DotNet Core WebApi项目搭建### JWT介绍

                DotNet Core WebApi项目搭建

                鉴权中心搭建(CoreWebApi)

                • 控制器代码

                  using System;
                  using System.Collections.Generic;
                  using System.Linq;
                  using System.Threading.Tasks;
                  using Microsoft.AspNetCore.Http;
                  using Microsoft.AspNetCore.Mvc;
                  using Microsoft.Extensions.Configuration;
                  using Microsoft.Extensions.Logging;
                  using Newtonsoft.Json;
                  using Test.Core.AuthenticationCenter.Utility;
                  namespace Test.Core.AuthenticationCenter.Controllers
                  {
                      [Route("api/[controller]")]
                      [ApiController]
                      public class AuthenticationController : ControllerBase
                      { 
                          #region MyRegion
                          private ILogger _logger = null;
                          private IJWTService _iJWTService = null;
                          private readonly IConfiguration _iConfiguration;
                          public AuthenticationController(ILoggerFactory factory,
                              ILogger logger,
                              IConfiguration configuration
                              , IJWTService service)
                          {
                              this._logger = logger;
                              this._iConfiguration = configuration;
                              this._iJWTService = service;
                          }
                          #endregion
                          [Route("Get")]
                          [HttpGet]
                          public IEnumerable Get()
                          {
                              return new List() { 1, 2, 3, 4, 6, 7 };
                          }
                          [Route("Login")]
                          [HttpGet]
                          public string Login(string name, string password)
                          {
                              ///这里肯定是需要去连接数据库做数据校验
                              if ("Richard".Equals(name) && "123456".Equals(password))//应该数据库
                              {
                                  string token = this._iJWTService.GetToken(name);
                                  return JsonConvert.SerializeObject(new
                                  {
                                      result = true,
                                      token
                                  });
                              }
                              else
                              {
                                  return JsonConvert.SerializeObject(new
                                  {
                                      result = false,
                                      token = ""
                                  });
                              }
                          }
                      }
                  }
                  
                • JWTService类代码

                  using Microsoft.Extensions.Configuration;
                  using Microsoft.IdentityModel.Tokens;
                  using System;
                  using System.Collections.Generic;
                  using System.IdentityModel.Tokens.Jwt;
                  using System.Linq;
                  using System.Security.Claims;
                  using System.Text;
                  using System.Threading.Tasks;
                  namespace Test.Core.AuthenticationCenter.Utility
                  {
                      public interface IJWTService
                      {
                          string GetToken(string UserName);
                      }
                      /// 
                      /// 备注下:代码演示的是对称加密,所以只有一个key,在返回的信息里面是没有的
                      /// PPT介绍时,说的是非对称的,那样是把解密key公开的,前面是后台用私钥加密的,
                      /// 可以保证别人解密后 拿到的数据  跟前面2部分hash后的结果一致 保证没有篡改
                      /// 此外,公钥不是在返回结果,那只是个打比方~
                      /// 
                      public class JWTService : IJWTService
                      {
                          private readonly IConfiguration _configuration;
                          public JWTService(IConfiguration configuration)
                          {
                              _configuration = configuration;
                          }
                          public string GetToken(string UserName)
                          {
                              Claim[] claims = new[]
                              {
                                 new Claim(ClaimTypes.Name, UserName),
                                 new Claim("NickName","Richard"),
                                 new Claim("Role","Administrator"),//传递其他信息  
                                 new Claim("abc","abccc")
                                 //new Claim
                              };
                              SymmetricSecurityKey key = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(_configuration["SecurityKey"]));
                              SigningCredentials creds = new SigningCredentials(key, SecurityAlgorithms.HmacSha256);
                              /**
                               *  Claims (Payload)
                                  Claims 部分包含了一些跟这个 token 有关的重要信息。 JWT 标准规定了一些字段,下面节选一些字段:
                                  iss: The issuer of the token,token 是给谁的
                                  sub: The subject of the token,token 主题
                                  exp: Expiration Time。 token 过期时间,Unix 时间戳格式
                                  iat: Issued At。 token 创建时间, Unix 时间戳格式
                                  jti: JWT ID。针对当前 token 的唯一标识
                                  除了规定的字段外,可以包含其他任何 JSON 兼容的字段。
                               * */
                              var token = new JwtSecurityToken(
                                  issuer: _configuration["issuer"],
                                  audience: _configuration["audience"],
                                  claims: claims,
                                  expires: DateTime.Now.AddMinutes(5),//5分钟有效期
                                  signingCredentials: creds);
                              string returnToken = new JwtSecurityTokenHandler().WriteToken(token);
                              return returnToken;
                          }
                      }
                  }
                  
                • DI依赖注入代码

                          // This method gets called by the runtime. Use this method to add services to the container.
                          public void ConfigureServices(IServiceCollection services)
                          {
                              services.AddScoped();//IOC DI容器依赖注入
                              services.AddControllers();
                          }
                  
                • 配置文件代码

                  {
                    "Logging": {
                      "LogLevel": {
                        "Default": "Information",
                        "Microsoft": "Warning",
                        "Microsoft.Hosting.Lifetime": "Information"
                      }
                    },
                    "AllowedHosts": "*",
                    "audience": "http://localhost:10086",
                    "issuer": "http://localhost:10086",
                    "SecurityKey": "MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDI2a2EJ7m872v0afyoSDJT2o1+SitIeJSWtLJU8/Wz2m7gStexajkeD+Lka6DSTy8gt9UwfgVQo6uKjVLG5Ex7PiGOODVqAEghBuS7JzIYU5RvI543nNDAPfnJsas96mSA7L/mD7RTE2drj6hf3oZjJpMPZUQI/B1Qjb5H3K3PNwIDAQAB"//Token密钥,可以使用私钥加密RSA后
                  }
                  

                  客户端(CoreWebApi)

                  • 控制器权限验证代码

                    using System;
                    using System.Collections.Generic;
                    using System.Linq;
                    using System.Threading.Tasks;
                    using Microsoft.AspNetCore.Authentication;
                    using Microsoft.AspNetCore.Authorization;
                    using Microsoft.AspNetCore.Http;
                    using Microsoft.AspNetCore.Mvc;
                    using Microsoft.Extensions.Logging;
                    namespace Test.Core.WebApi.Controllers
                    {
                        [Route("api/[controller]")]
                        [ApiController]
                        [Authorize]//鉴权
                        public class AuthorizeController : ControllerBase
                        {
                            private ILogger _Logger = null;
                            public AuthorizeController(ILogger logger)
                            {
                                this._Logger = logger;
                                _Logger.LogInformation($"{nameof(AuthorizeController)} 被构造。。。。 ");
                            }
                            [HttpGet]
                            [Route("Get")]
                            [AllowAnonymous]//跳过鉴权
                            public IActionResult Get()
                            {
                                return new JsonResult(new
                                {
                                    Data = "这个是OK的,这个Api并没有要求授权!"
                                });
                            }
                            [HttpGet]
                            [Route("GetAuthorizeData")]
                           // [Authorize] //Microsoft.AspNetCore.Authorization
                            public IActionResult GetAuthorizeData()
                            { 
                                //读取Token中的信息
                              var Name = base.HttpContext.AuthenticateAsync().Result.Principal.Claims.FirstOrDefault(a=>a.Type.Equals("Name"))?.Value;
                                Console.WriteLine($"this is Name {Name}"); 
                                return new JsonResult(new
                                {
                                    Data = "已授权",
                                    Type = "GetAuthorizeData" 
                                    //Claims=Newtonsoft.Json.JsonConvert.SerializeObject(Claims)
                                });
                            }
                        }
                    }
                    
                  • Startup.cs中注册服务

                            // This method gets called by the runtime. Use this method to add services to the container.
                            public void ConfigureServices(IServiceCollection services)
                            {                     
                                #region JWT鉴权授权
                                //1.Nuget引入程序包:Microsoft.AspNetCore.Authentication.JwtBearer 
                                //services.AddAuthentication();//禁用  
                                var ValidAudience = this.Configuration["audience"];
                                var ValidIssuer = this.Configuration["issuer"];
                                var SecurityKey = this.Configuration["SecurityKey"];
                                services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)  //默认授权机制名称;                                     
                                         .AddJwtBearer(options =>
                                         {
                                             options.TokenValidationParameters = new TokenValidationParameters
                                             {
                                                 ValidateIssuer = true,//是否验证Issuer
                                                 ValidateAudience = true,//是否验证Audience
                                                 ValidateLifetime = true,//是否验证失效时间
                                                 ValidateIssuerSigningKey = true,//是否验证SecurityKey
                                                 ValidAudience = ValidAudience,//Audience
                                                 ValidIssuer = ValidIssuer,//Issuer,这两项和前面签发jwt的设置一致  表示谁签发的Token
                                                 IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(SecurityKey))//拿到SecurityKey
                                                 //AudienceValidator = (m, n, z) =>
                                                 //{
                                                 //    return m != null && m.FirstOrDefault().Equals(this.Configuration["audience"]);
                                                 //},//自定义校验规则,可以新登录后将之前的无效 
                                             };
                                         });
                                #endregion
                            }
                    
                  • 注册中间件

                            // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
                            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
                            {
                                //使用中间件
                                #region 通过中间件来支持鉴权授权
                                app.UseAuthentication();
                                #endregion
                            }
                    

                    跨域

                    同源策略

                    • 浏览器的同源策略阻止跨域

                      同源策略(Same Origin Policy)是一种约定,它是浏览器最核心也最基本的安全功能,如果缺少了同源策略,则浏览器的正常功能可能都会受到影响。可以说Web是构建在同源策略基础之上的,浏览器只是针对同源策略的一种实现。

                      同源策略会阻止一个域的JS脚本和另外一个域的内容进行交互。

                      DotNet Core WebApi项目搭建

                      解决跨域问题的途径。

                      DotNet Core WebApi项目搭建

                      1. JSONP是基于前端使用特定的标签访问可以绕开浏览器的跨域验证。

                      2. 前端网站不直接通过浏览器请求HTTP而是调用一个本地方法,方法中模拟了一个HTTP请求,从而绕开了浏览器。

                        • 在Index.cshtml文件url中将Http请求改为一个方法(基于MVC项目演示)
                          @{
                              ViewData["Title"] = "Home Page";
                          }
                          
                            请求数据: 
                          $.ajax({ type: "Get", data: {}, url: "GetCrossDaminData", //为解决跨域,url中将Http请求改为一个方法 success: function (result) { $("#result").text(result); } })
                          • 在HomeController.cs对应的方法中模拟一个HTTP请求
                            [HttpGet]
                            [Route("GetCrossDaminData")]
                            public string GetCrossDaminData()
                            {
                                //我这里去模拟Http请求获取到数据以后再返回给前端
                                string url = "http://localhost:8004/api/CrossDamin/GetCrossDaminData"; 
                                using (HttpClient httpClient = new HttpClient())
                            	{
                                	HttpRequestMessage message = new HttpRequestMessage();
                                    message.Method = HttpMethod.Get;
                                    message.RequestUri = new Uri(url);
                                    var result = httpClient.SendAsync(message).Result;
                                    string content = result.Content.ReadAsStringAsync().Result;
                                    return content;
                            	}
                            }
                            
                          • 配置服务器使服务器允许跨域

                            • 在响应头中增加Access-Control-Allow-Origin字段

                              using Microsoft.AspNetCore.Authorization;
                              using Microsoft.AspNetCore.Mvc;
                              using Test.Core.WebApi.Utility;
                              namespace Test.Core.WebApi.Controllers
                              {
                                  [Route("api/[controller]")]
                                  [ApiController]
                                  //[CrossDomainFilterAttribute] //通过IActionFilter在响应头中增加Access-Control-Allow-Origin字段,实现跨域
                                  public class CrossDaminController : ControllerBase
                                  {
                                      [HttpGet]
                                      [Route("GetCrossDaminData")] 
                                      [CrossDomainFilterAttribute] //通过IActionFilter在响应头中增加Access-Control-Allow-Origin字段,实现跨域
                                      public string GetCrossDaminData()
                                      {  
                                          //base.HttpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*"); //在响应头中增加Access-Control-Allow-Origin字段,实现跨域
                                          return Newtonsoft.Json.JsonConvert.SerializeObject(
                                              new { 
                                              id=123,
                                              Name="开塔克撞火车",
                                              Description="这个Api 就是专门用测试跨域问题。。"
                                              });
                                      }       
                                  }
                              }
                              
                              using Microsoft.AspNetCore.Mvc.Filters;
                              using System;
                              namespace Test.Core.WebApi.Utility
                              {
                                  public class CrossDomainFilterAttribute : Attribute, IActionFilter
                                  {
                                      //无论是在OnActionExecuted、OnActionExecuting 来指定跨域都可以;但是两个方法里面不能同时都指定;
                                      public void OnActionExecuted(ActionExecutedContext context)
                                      {
                                          #region 支持跨域
                                          context.HttpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
                                          #endregion
                                      }
                                      public void OnActionExecuting(ActionExecutingContext context)
                                      {
                                          //#region 支持跨域
                                          //context.HttpContext.Response.Headers.Add("Access-Control-Allow-Origin", "*");
                                          //#endregion
                                      }
                                  }
                              }
                              
                            • 使用Cors Nuget包并注册服务

                              中间件支持跨域,依赖于程序包:Microsoft.AspNetCore.Cors

                      services.AddCors(option => option.AddPolicy("AllowCors", build =>build.AllowAnyOrigin().AllowAnyMethod()));
                      app.UseCors("AllowCors"); //必须要在UseRouting之后 在UseAuthorization之前。
                      
                        public void ConfigureServices(IServiceCollection services)
                              {
                                   services.AddCors(option => option.AddPolicy("AllowCors", _build => _build.AllowAnyOrigin().AllowAnyMethod()));
                              }
                              public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
                             {
                                   //使用中间件
                                   app.UseRouting();
                                   app.UseCors("AllowCors");
                                   #region 通过中间件来支持鉴权授权
                                   app.UseAuthentication();
                                   #endregion             
                                   app.UseAuthorization();
                             }
                      
免责声明:我们致力于保护作者版权,注重分享,被刊用文章因无法核实真实出处,未能及时与作者取得联系,或有版权异议的,请联系管理员,我们会立即处理! 部分文章是来自自研大数据AI进行生成,内容摘自(百度百科,百度知道,头条百科,中国民法典,刑法,牛津词典,新华词典,汉语词典,国家院校,科普平台)等数据,内容仅供学习参考,不准确地方联系删除处理! 图片声明:本站部分配图来自人工智能系统AI生成,觅知网授权图片,PxHere摄影无版权图库和百度,360,搜狗等多加搜索引擎自动关键词搜索配图,如有侵权的图片,请第一时间联系我们。

相关阅读

目录[+]

取消
微信二维码
微信二维码
支付宝二维码