我正在使用Angular和ASP.NET Core构建一个网站 .
在某些页面上,我想从Web API获取数据 . 当我运行应用程序时,浏览器(Firefox)显示
跨源请求被阻止:同源策略不允许在...(URL)读取远程资源(原因:CORS Headers '来自CORS预检信道的'访问控制允许 - Headers '中缺少令牌'授权') .
我试过其他浏览器,得到了同样的错误 .
出于授权考虑,我使用 HttpInterceptor
为Angular前端的每个请求插入一个授权标头 .
然后我查看了我的ASP.NET Core后端 . 我将CORS策略设置为 app.UseCors(builder => { builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader(); });
,但它仍然不起作用 .
我用Postman测试了API,它运行正常 .
哪里出错了?
Startup.cs
文件 .
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().AddJsonOptions(
opt => opt.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
);
// In production, the Angular files will be served from this directory
services.AddSpaStaticFiles(configuration =>
{
configuration.RootPath = "ClientApp/dist";
});
services.AddEntityFrameworkSqlServer();
services.AddCors();
services.AddSignalR();
services.AddDbContext<ApplicationDbContext>(opt =>
{
opt.UseSqlServer(Configuration.GetConnectionString("Remote"));
});
services.AddIdentity<ApplicationUser, IdentityRole>(opts =>
{
opts.Password.RequireDigit = true;
opts.Password.RequireLowercase = true;
opts.Password.RequireUppercase = true;
opts.Password.RequireNonAlphanumeric = false;
opts.Password.RequiredLength = 7;
}).AddEntityFrameworkStores<ApplicationDbContext>();
services.AddAuthentication(opts =>
{
opts.DefaultScheme = JwtBearerDefaults.AuthenticationScheme;
opts.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
opts.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(cfg =>
{
cfg.RequireHttpsMetadata = false;
cfg.TokenValidationParameters = new TokenValidationParameters()
{
ValidIssuer = Configuration["Auth:Jwt:Issuer"],
ValidAudience = Configuration["Auth:Jwt:Audience"],
IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(Configuration["Auth:Jwt:Key"])),
ClockSkew = TimeSpan.Zero,
RequireExpirationTime = true,
ValidateIssuerSigningKey = true,
ValidateAudience = true
};
});
services.AddAuthorization(options =>
{
options.AddPolicy("NonUser", policy => policy.RequireRole("RestrauntOwner", "RestrauntAdmin", "SystemAdmin"));
});
}
// 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.UseExceptionHandler("/Home/Error");
}
app.UseCors(builder => { builder.AllowAnyOrigin().AllowAnyMethod().AllowAnyHeader(); });
app.UseStaticFiles();
app.UseSpaStaticFiles();
app.UseAuthentication();
app.UseMvc(routes =>
{
routes.MapRoute(
name: "default",
template: "{controller}/{action=Index}/{id?}");
});
app.UseSignalR(route =>
{
route.MapHub<OrderHub>("/orderhub");
});
app.UseCookiePolicy();
app.UseSpa(spa =>
{
// To learn more about options for serving an Angular SPA from ASP.NET Core,
// see https://go.microsoft.com/fwlink/?linkid=864501
spa.Options.SourcePath = "ClientApp";
if (env.IsDevelopment())
{
spa.UseAngularCliServer(npmScript: "start");
}
});
}
}
有点奇怪 . 我一直在我的Windows PC上开发这个 . 我在我的MacBook上克隆了这个项目,它在macOS上没有任何问题 .
3 回答
如果你不能在这里工作,那么有几个提示:
您的出处必须与浏览器发送的内容完全匹配 .
如果是HTTP,则必须放置HTTP,HTTPS必须为HTTPS .
也必须包含端口号并且正确 .
因此,如果您使用相同的URL,请不要为
"http://localhost:5001"
设置CORS规则!在浏览器或Fiddler中查找完全正确的内容并确保它符合您的预期 . 如果在HTTP和HTTPS之间切换,很容易混淆 .
如果您发送的内容不匹配,您将获得一个空的响应204
Headers 不区分大小写
"authorization"
或"Authorization"
或"aUtHoRiZaTiOn"
.你必须包括方法和 Headers
WithMethods
或AllowAnyMethod
指定允许的HTTP方法,则无效 . 这很容易错过 - 特别是对于GET请求 .如果使用中间件或分支MVC管道,您可以在该级别添加CORS .
对于
app.UseSpa
(如果您是SPA的托管机制),您可以执行此操作Fiddler很有用
Fiddler将向您展示CORS成功所需的条件 . 这是
authorization
header和GET
方法 .在更改服务器配置后,您可以在先前的请求上按
R
重新运行它 . 这样您就不必继续启动浏览器了 .请务必查看响应部分中的
Headers
,因为即使成功,实际内容也将为0字节 .此错误背后的原因是:您的客户端项目和webapi位于不同的域(或端口)上 .
要为应用程序设置CORS,请将 Microsoft.AspNetCore.Cors 包添加到项目中 .
然后使用中间件启用CORS:在启动> ConfigureServices方法中
在Configure方法中:
欲了解更多信息read here
好 . 我发现没错,虽然有点傻 .
我问过网络API提供商 . 他告诉我,这是因为不允许授权 Headers .
我使用
HttpIntercepter
将授权标头插入到Angular前端触发的每个请求中 . 我这样做是为了让我的ASP.NET Core Web API对站点用户进行身份验证 . 但是开放式Web API不允许使用此标头 .如果我没有登录我的网站,它会工作,但如果我执行登录程序,它将获得一个令牌并在请求中插入一个授权,它将触发一个OPTIONS预检请求,然后请求将被封锁
这样一个愚蠢的问题:)我必须找到一种新方法来做到这一点 .