打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
.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"  }}
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
ASP.NET Core 5.0 Web API 自动集成Swashbuckle
.Net Core2.2升级到3.1小记
asp.net 2.0升级到2.1
使用Visual Studio Code开发Asp.Net Core WebApi学习笔记(九)
ASP.NET Core Web API 学习笔记(3): Logger
ASP.NET Core3基础:01. 示例项目搭建与启动顺序
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服