zoukankan      html  css  js  c++  java
  • .NET Core 3 Web Api Cors fetch 一直 307 Temporary Redirect

    .NET Core 3 Web Api Cors fetch 一直 307 Temporary Redirect

    继上一篇 .net core 3 web api jwt 一直 401 为添加JWT-BearerToken认证所述的坑后,
    本次为添加CORS跨域,又踩坑了。

    自从 .NET Core 2.2 之后,CORS跨域配置代码发生了很大变化。
    在 .NET Core 3.1 中,本作者碰到各种HTTP错误,诸如 500、307、401 等错误代码...
    在必应Bing和不断Debug调整配置代码位置后,得知:

    1. AllowAnyOrigin 方法,在新的 CORS 中间件已经被阻止使用允许任意 Origin,所以该方法无效。
    2. AllowCredentials 方法,自从 .NET Core 2.2 之后,不允许和AllowAnyOrigin同时调用。
    3. WithOrigins 方法,在 .NET Core 3.1 中有bug,具体原因未知,暂时只能用SetIsOriginAllowed(t=> true)代替,等效.AllowAnyOrigin方法。
    4. 创建项目默认的模板中,app.UseHttpsRedirection()在前面,所以我将app.UseCors()放在它后面,这是导致HTTP 307 Temporary Redirect福报的根本原因之一。
    5. 度娘告诉我,app.UseCors()方法要在app.UseAuthentication()之后,是误人子弟的,其实放在它前面也可以,并且app.UseCors()要在app.UseRouting()之后,app.UseEndpoints()app.UseHttpsRedirection()之前
    6. 使用fetch跨域请求时,要注意controller的action是否有设置除了HttpOptions之外的其它Http Method方法,如果有要加上HttpOptions标记特性,因为fetch跨域请求会先执行OPTIONS预请求。
    7. 使用fetch请求需要JWT认证的接口时,除了在HTTP Headers设置Authorization之外,还需要设置'credentials': 'include'
    8. app.UseXxxxxx方法,引入中间件时,要注意管道(Middleware)注册顺序。

    参考:

    源代码

    以下是在 .NET Core 3.1下经过严谨测试,可以JWT认证CORS跨域IIS托管自寄主运行的源代码,仅供参考。

    WebApi.csproj

    <Project Sdk="Microsoft.NET.Sdk.Web">
      <PropertyGroup>
        <TargetFramework>netcoreapp3.1</TargetFramework>
        <RootNamespace>WebApi</RootNamespace>
      </PropertyGroup>
      <ItemGroup>
        <PackageReference Include="Microsoft.AspNetCore.Authentication.JwtBearer" Version="3.1.2" />
        <PackageReference Include="Microsoft.Extensions.Logging.Console" Version="3.1.2" />
        <PackageReference Include="Microsoft.Extensions.Logging.Debug" Version="3.1.2" />
        <PackageReference Include="Microsoft.Extensions.Logging.EventSource" Version="3.1.2" />
        <PackageReference Include="Microsoft.Extensions.Logging.TraceSource" Version="3.1.2" />
        <PackageReference Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="3.1.2" />
        <PackageReference Include="Microsoft.TeamFoundationServer.Client" Version="16.153.0" />
        <PackageReference Include="Microsoft.VisualStudio.Services.Client" Version="16.153.0" />
        <PackageReference Include="Microsoft.VisualStudio.Services.InteractiveClient" Version="16.153.0" />
        <PackageReference Include="NLog.Web.AspNetCore" Version="4.9.0" />
      </ItemGroup>
    </Project>
    

    Program.cs

    using Microsoft.AspNetCore.Hosting;
    using Microsoft.Extensions.Hosting;
    using Microsoft.Extensions.Logging;
    using NLog.Extensions.Logging;
    using System.Diagnostics;
    using System.IO;
    
    namespace WebApi
    {
        public class Program
        {
            public static void Main(string[] args)
            {
                CreateHostBuilder(args).Build().Run();
            }
    
            public static IHostBuilder CreateHostBuilder(string[] args)
            {
                return Host.CreateDefaultBuilder(args)
                    .ConfigureLogging((context, logging) =>
                    {
                        logging.ClearProviders()
    #if DEBUG
                            .AddConsole()
                            .AddDebug()
                            .AddEventLog()
                            .AddTraceSource(new SourceSwitch(nameof(Program), "Warning"), new ConsoleTraceListener())
    #endif
                            .AddNLog();
                    })
                    .ConfigureWebHostDefaults(webBuilder =>
                    {
                        webBuilder.UseContentRoot(Directory.GetCurrentDirectory())
                           .UseKestrel()
                           .UseIISIntegration()
                           .UseIIS()
                           .UseStartup<Startup>();
                    });
            }
        }
    }
    

    Startup.cs

    using MCS.Vsts.Options;
    using MCS.Vsts.Services;
    using Microsoft.AspNetCore.Authentication.JwtBearer;
    using Microsoft.AspNetCore.Builder;
    using Microsoft.AspNetCore.Hosting;
    using Microsoft.AspNetCore.HttpOverrides;
    using Microsoft.Extensions.Configuration;
    using Microsoft.Extensions.DependencyInjection;
    using Microsoft.Extensions.Hosting;
    using Microsoft.IdentityModel.Tokens;
    using System.Text;
    
    namespace WebApi
    {
        public class Startup
        {
            public IConfiguration Configuration { get; }
    
            public Startup(IConfiguration configuration)
            {
                Configuration = configuration;
            }
    
            public void ConfigureServices(IServiceCollection services)
            {
                services.AddControllers();
    
                //认证
                services.AddAuthentication(JwtBearerDefaults.AuthenticationScheme)
                    .AddJwtBearer(options =>
                    {
                        var secretBytes = Encoding.UTF8.GetBytes(Configuration["ServerConfig:Secret"]);
                        options.TokenValidationParameters = new TokenValidationParameters()
                        {
                            IssuerSigningKey = new SymmetricSecurityKey(secretBytes),
                            ValidateIssuer = false,
                            ValidateAudience = false,
                            ValidateActor = false,
                            RequireSignedTokens = true,
                            RequireExpirationTime = true,
                            ValidateLifetime = true
                        };
                    });
    
                //跨域
                services.AddCors(options =>
                {
                    options.AddDefaultPolicy(builder =>
                    {
                        builder
                        //允许任何来源的主机访问
                        //TODO: 新的 CORS 中间件已经阻止允许任意 Origin,即设置 AllowAnyOrigin 也不会生效
                        //AllowAnyOrigin()
                        //设置允许访问的域
                        //TODO: 目前.NET Core 3.1 有 bug, 暂时通过 SetIsOriginAllowed 解决
                        //.WithOrigins(Configuration["CorsConfig:Origin"])
                        .SetIsOriginAllowed(t=> true)
                        .AllowAnyMethod()
                        .AllowAnyHeader()
                        .AllowCredentials();
                    });
                });
    
                //TODO: do something...
            }
    
            public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
            {
                if (env.IsDevelopment())
                {
                    app.UseDeveloperExceptionPage();
                }
                else
                {
                    //Enabled HSTS
                    app.UseHsts();
                }
    
                //TODO: 要放在UseCors之后
                //app.UseHttpsRedirection();
    
                app.UseRouting();
    
                app.UseForwardedHeaders(new ForwardedHeadersOptions
                {
                    ForwardedHeaders = ForwardedHeaders.XForwardedFor | ForwardedHeaders.XForwardedProto
                });
    
                //TODO: UseCors要在UseRouting之后,UseEndpoints 和 UseHttpsRedirection 之前
                app.UseCors();
    
                app.UseAuthentication();
    
                app.UseAuthorization();
    
                app.UseHttpsRedirection();
    
                app.UseEndpoints(endpoints =>
                {
                    endpoints.MapControllers();
                });
            }
        }
    }
    

    appsettings.json

    {
      "Logging": {
        "LogLevel": {
          "Default": "Information",
          "Microsoft": "Warning",
          "Microsoft.Hosting.Lifetime": "Information"
        }
      },
      "AllowedHosts": "*",
      "https_port": 44370,
      "urls": "http://*:50867",
      "ServerConfig": {
        "Secret": "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
      },
      "CorsConfig": {
        "BaseUri": "http://myserver"
      }
    }
    
  • 相关阅读:
    领扣(LeetCode)七进制数 个人题解
    ie固定table单元格宽度
    js 阻止冒泡
    在jsp页面下, 让eclipse完全支持HTML/JS/CSS智能提示(转)
    WebStorm 6.0 与 7.0 注册码
    统制Highcharts中x轴和y轴坐标值的密度
    ie版本
    flash透明 处于最低
    eclipse svn --
    jquery---- 数组根据值进行删除
  • 原文地址:https://www.cnblogs.com/VAllen/p/dotnet-core-3-cors-fetch-response-307-temporary-redirect.html
Copyright © 2011-2022 走看看