使用GET的CORS请求有效,但POST不起作用-ASP .NET CORE和使用JWT Auth

时间:2019-01-02 06:24:39

标签: asp.net asp.net-core cors http-headers jwt

如果我正在执行GET请求,则工作正常,但是POST请求不起作用。我已经搜索了几个小时,无法弄清楚,基本上我已经看到了所有建议,我已经尝试过了。

这是我的Configure函数:

// 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()) //Remember to switch launchSettings.json to 'Production'
    {
        app.UseDeveloperExceptionPage();
        app.UseDatabaseErrorPage();

        if (IsDebug) //Allows testing by using a frontend at localhost:8080 - Configure the port to your frontend port.
        {
            app.UseCors(builder => builder
                .WithOrigins("http://localhost:8080")
                .AllowAnyMethod()
                .AllowAnyHeader()
                .AllowCredentials()
            );                  
        }
    }
    else
    {
        app.UseExceptionHandler("/Error");
        app.UseHsts();
    }

    app.UseHttpsRedirection();
    app.UseStaticFiles();
    app.UseCookiePolicy();
    app.UseAuthentication();

    app.UseMvc(routes =>
    {
        routes.MapRoute("default", "{controller=Home}/{action=Index}/{id?}");
        routes.MapRoute("Error", "{*url}", new { controller = "Home", action = "Index" });
    });

}

我要先注册CORS中间件。

对于我要调用的方法,我将[Authorize]放在类上,并将[HttpPost]放在方法上。如果我将其切换为[HttpGet],则可以使用。

以下是我如何调用API的示例:

var headers = {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer ' + jwtToken
}

// Don't burden the server with unnecessary calls to the API if we don't even have a token.
if (jwtToken) {
    var result = await axios.post('https://localhost:44377/api/Playground/GetMenuItems', { headers: headers } );
    if (result.data === -1) { throw -1 }    
    return result.data;
}

这是我的网络工具的外观:

enter image description here

我相信第一个是预检,因为请求方法是OPTIONS,它返回204:

enter image description here

这是失败的POST请求,失败为401:

enter image description here

注意如何在请求中不发送承载令牌。但是,它是在请求有效负载中发送的。

我绝对在这里挠头,如果有人有见识,我将不胜感激!

干杯。

P.S。这是我的ConfigureServices函数:

public void ConfigureServices(IServiceCollection services)
{
    services.Configure<CookiePolicyOptions>(options =>
    {
        // This lambda determines whether user consent for non-essential cookies is needed for a given request.
        options.CheckConsentNeeded = context => true;
        options.MinimumSameSitePolicy = SameSiteMode.None;
    });

    services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(ConnectionString));
    services.AddDefaultIdentity<IdentityUser>().AddEntityFrameworkStores<ApplicationDbContext>();


    JwtSecurityTokenHandler.DefaultInboundClaimTypeMap.Clear(); // => remove default claims
    services
    .AddAuthentication(options =>
    {
        options.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
        options.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;

    })
    .AddJwtBearer(cfg =>
    {
        cfg.RequireHttpsMetadata = false;
        cfg.SaveToken = true;
        cfg.TokenValidationParameters = new TokenValidationParameters
        {
            ValidIssuer = Configuration["JwtIssuer"],
            ValidAudience = Configuration["JwtIssuer"],
            IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["JwtKey"])),
            ClockSkew = TimeSpan.Zero // remove delay of token when expire
        };
    });


    services.AddMvc().SetCompatibilityVersion(CompatibilityVersion.Version_2_1);


    if (IsDevelopment)
    {
        IsDebug = Configuration.GetValue<bool>("DEBUGGING");
        if (IsDebug)
        {
            services.AddCors(); //Dangerous in prod.
        }

        _connectionString = Configuration["PlaygroundConnectionString"];
    }
    else
    {
        // Get prod secrets
    }

}

1 个答案:

答案 0 :(得分:1)

Axios.post需要3个参数-您仅提供了2个。第二个参数是data对象,它是post命令的正文,它说明了为什么标头是在正文中发送的。

来自axios documentation

  

axios.post(URL [,data [,config]])

尝试将代码更改为

var result = await axios.post('https://localhost:44377/api/Playground/GetMenuItems', null, { headers: headers } );

Axios.get命令仅需要2个参数,这就是为什么该参数起作用的原因。