【发布时间】:2021-02-14 22:49:39
【问题描述】:
我在开发 Angular 8、ASP NET Core Web Api Web 应用程序时遇到了 CORS 策略问题。我的 Angular 应用程序在 http://localhost:4200 上运行 为与 Web Api 通信创建了一项服务。如下所示
@Injectable({
providedIn: 'root'
})
export class AuthenticationService {
apiUrl: string = "";
constructor(private http: HttpClient) {
this.apiUrl = 'https://localhost:44316';
}
login(Username: any, Password: any){
return this.http.post<Observable<ResultItem<AuthenticationResponse>>>(this.apiUrl + "/api/User/Authenticate", {Username: Username, Password: Password});
}
}
Services 稍后在组件中调用,但它只是被注入,并与 subscribe 方法一起使用。
onLogin(){
this.authenticationService.login(this.loginFormValues.username.value, this.loginFormValues.password.value).subscribe(
result => {});
}
Web Api 在 https://localhost:44316/ 上单独运行 从 Angular 调用的方法的终点如下所示:
[ApiController]
[Route("api/[controller]")]
public class UserController : ControllerBase
{
private readonly IUserService userService;
public UserController(IUserService userService)
{
this.userService = userService;
}
[HttpPost("Authenticate")]
public async Task<IActionResult> Authenticate(AuthenticationModel model)
{
return Ok(await userService.Login(model));
}
}
我最关心的是我的启动文件。到目前为止,我已经尝试在那里更改 CORS 设置,但没有成功。 Startup.cs 文件的代码如下所示。
快速注释:
ConfigureServices 方法中的两行代码使用了我的一些外部函数,它们的目的是:
-
AddSubstracture:将所有存储库注册为瞬态并注册 DbContext。
-
AddApplication:将存储库上一层的服务注册为瞬态
Startup.cs 代码如下
public class Startup
{
private IServiceCollection _services;
public Startup(IConfiguration configuration, IWebHostEnvironment environment)
{
Configuration = configuration;
Environment = environment;
SportFacilityUnitSettings = configuration.Get<SportFacilityUnitSettings>();
}
public IConfiguration Configuration { get; }
public IWebHostEnvironment Environment { get; }
public SportFacilityUnitSettings SportFacilityUnitSettings { get; }
public void ConfigureServices(IServiceCollection services)
{
services.AddCors();
services.AddMvc(option => option.EnableEndpointRouting = false);
services.AddSubstructure(Configuration, Environment, SportFacilityUnitSettings);
services.AddApplication();
services.AddScoped<IPasswordHasher<User>, PasswordHasher<User>>();
var appSettingsSection = Configuration.GetSection("AppSettings");
services.Configure<AppSettings>(appSettingsSection);
var appSettings = appSettingsSection.Get<AppSettings>();
var key = Encoding.ASCII.GetBytes(appSettings.Secret);
services.AddAuthentication(x =>
{
x.DefaultAuthenticateScheme = JwtBearerDefaults.AuthenticationScheme;
x.DefaultChallengeScheme = JwtBearerDefaults.AuthenticationScheme;
})
.AddJwtBearer(x =>
{
x.RequireHttpsMetadata = false;
x.SaveToken = true;
x.TokenValidationParameters = new TokenValidationParameters
{
ValidateIssuerSigningKey = true,
IssuerSigningKey = new SymmetricSecurityKey(key),
ValidateIssuer = false,
ValidateAudience = false
};
});
services.AddControllers().AddNewtonsoftJson(options =>
options.SerializerSettings.ReferenceLoopHandling = Newtonsoft.Json.ReferenceLoopHandling.Ignore
);
services.Configure<AppSettings>(Configuration.GetSection("AppSettings"));
services.AddHttpContextAccessor();
_services = services;
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseCors(
options => options.SetIsOriginAllowed(x => _ = true).AllowAnyMethod().AllowAnyHeader().AllowCredentials()
);
app.UseMvc();
app.UseHsts();
app.UseMiddleware<JwtMiddleware>();
app.UseAuthentication();
app.UseRouting();
app.UseHttpsRedirection();
app.UseStaticFiles();
app.UseAuthorization();
app.UseEndpoints(endpoints =>
{
endpoints.MapControllers();
});
}
}
当我点击用于发送请求的登录按钮时,我在 Web 浏览器控制台中收到以下错误。
从源“http://localhost:4200”访问“https://localhost:44316/api/User/Authenticate”处的 XMLHttpRequest 已被 CORS 策略阻止:无“访问控制允许源”请求的资源上存在标头。
最奇怪的是,当我调试它并在 Api 层设置断点时,调试器命中它,然后它进入服务层并在 Authentication 方法中的某个地方失败。
【问题讨论】:
-
如果你调试的时候碰到API,那肯定不是CORS问题。
-
Chrome 往往会显示错误消息,即使是与 CORS 无关的问题。
-
如何发送不记名令牌以从 Angular 应用程序进行身份验证?
-
@G-Man 你是对的,Cors 错误具有误导性,并且在更新某些身份验证数据时,错误与 .AsNoTracking() 选项有关。感谢您的支持。
标签: asp.net angular asp.net-core cors