原始的'http:// localhost:4200'已被SignalR的CORS策略所禁止,使用带有角度的.net内核

问题描述 投票:0回答:1

[我正在使用信号来获取我的角度应用程序中的实时数据,并使用.net core 2.2 API作为后端,但是当我运行项目时,在浏览器控制台中出现了CORS错误。

VehicleHub.cs

using Microsoft.AspNetCore.SignalR;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace BusinessLayer.HubConfig
{
    public class VehicleHub:Hub
    {
        public int id { get; set; }
        public string name { get; set; }
        public string vehicleType { get; set; }
        public string modelNo { get; set; }
        public string registrationNo { get; set; }
        public int? lcsVehicleNo { get; set; }
        public int relationShipOfficerId { get; set; }
        public int driverId { get; set; }
        public string driverName { get; set; }
        public string relationShipOfficerName { get; set; }
        public bool isActive { get; set; }
        public DateTime createdOn { get; set; }
        public string createdBy { get; set; }
        public DateTime modifiedOn { get; set; }
        public string modifyBy { get; set; }
        public int locationId { get; set; }
        public int createdById { get; set; }
        public int? modifyById { get; set; }
    }
}

这是我的starup.cs文件

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using BusinessLayer.Helpers;
using MatechEssential;
using Microsoft.AspNetCore.Authentication.Cookies;
using Microsoft.AspNetCore.Authentication.JwtBearer;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.HttpsPolicy;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Microsoft.IdentityModel.Tokens;
using WebAPICore.Helpers;
using WebAPICore.middleware;
using WebAPICore.Services;
using WebAPICore.Utility;
using BusinessLayer.HubConfig;

namespace WebAPICore
{
    public class Startup
    {
        private readonly IHostingEnvironment _hostingEnvironment;

        public Startup(IConfiguration configuration, IHostingEnvironment env)
        {
            Configuration = configuration;
            _hostingEnvironment = env;
        }

        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.AddCors(o => o.AddPolicy("CorsPolicy", builder =>
            {
                builder.AllowAnyOrigin()
                       .AllowAnyMethod()
                       .AllowAnyHeader()
                       .SetIsOriginAllowed((host) => true);
            }));
            services.AddSignalR();
            services.AddMvc(options =>
            {
                options.Filters.Add(new ErrorHandlingFilter());
            }).SetCompatibilityVersion(CompatibilityVersion.Version_2_2);

            // configure strongly typed settings objects
            var appSettingsSection = Configuration.GetSection("AppSettings");
            services.Configure<AppSettings>(appSettingsSection);

            // configure jwt authentication
            var appSettings = appSettingsSection.Get<AppSettings>();
            SQLHelper._ConStr = appSettings.ConnectionString != null? appSettings.ConnectionString:"" ;

            var key = Encoding.ASCII.GetBytes(appSettings.Secret);
            services.AddAuthentication(x =>
            {
                x.DefaultAuthenticateScheme = "bearer";
                x.DefaultChallengeScheme = "bearer";
            })
            .AddJwtBearer("bearer", options =>
            {
                options.TokenValidationParameters = new TokenValidationParameters
                {
                    ValidateAudience = false,
                    ValidateIssuer = false,
                    ValidateIssuerSigningKey = true,
                    IssuerSigningKey = new SymmetricSecurityKey(Encoding.UTF8.GetBytes(appSettings.Secret)),
                    ValidateLifetime = true,
                    ClockSkew = TimeSpan.Zero
                    // TimeSpan.Zero //the default for this setting is 5 minutes
                };
                options.Events = new JwtBearerEvents
                {
                    OnAuthenticationFailed = context =>
                    {
                        if (context.Exception.GetType() == typeof(SecurityTokenExpiredException))
                        {
                            context.Response.Headers.Add("Token-Expired", "true");
                        }
                        return Task.CompletedTask;
                    }
                };
                options.SaveToken = true;
            });

            var physicalProvider = _hostingEnvironment.ContentRootFileProvider;
            var embeddedProvider = new EmbeddedFileProvider(Assembly.GetEntryAssembly());
            var compositeProvider = new CompositeFileProvider(physicalProvider, embeddedProvider);
             string absolutePath = compositeProvider.GetFileInfo("/SetupFiles/MasterSetupData.xml").PhysicalPath;
            XmlToList.xmlFileType = absolutePath;

            services.AddTransient<IHttpContextAccessor, HttpContextAccessor>();
            services.AddTransient<UserResolverService>();    
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory logger)
        {
            if (env.IsDevelopment())
            {
                app.UseDeveloperExceptionPage();
               app.UseApiExceptionHandler(logger);
            }
            else
            {
                // The default HSTS value is 30 days. You may want to change this for production scenarios, see https://aka.ms/aspnetcore-hsts.
                app.UseHsts();
               app.UseApiExceptionHandler(logger); //use global exception handlers
            }
            app.UseSignalR(routes =>
            {
                routes.MapHub<VehicleHub>("/Utility/GetAllVehicles");
            });
            // global cors policy
            app.UseCors("CorsPolicy");

            app.UseAuthentication();
            app.UseHttpsRedirection();
            app.UseResponseWrapper();

            //app.UseAPIResponseWrapperMiddleware();
            app.UseOptions();
            app.UseMvc();
        }
    }
}

UtilityController.cs

[Route("api/[controller]")]
    [ApiController]
    [EnableCors("CorsPolicy")]
    public class UtilityController : ControllerBase
    {
        private UserModel _currentUser;
        private IHubContext<VehicleHub> _hub;
        public UtilityController(UserResolverService userService, IHubContext<VehicleHub> hub)// , IUserService userService
        {
            _hub = hub;
            _currentUser = userService.getUserInfo();
        }
 [HttpGet]
        [Route("GetAllVehicles")]
        public IActionResult GetAllVehicles()
        {
            try
            {
                _hub.Clients.All.SendAsync("transferchartdata", UtilityFuncation.GetVehicleAll());
                return Ok(new { Message = "Request Completed" });
            }
            catch (Exception exp)
            {
                return NotFound(CommonApiResponse.Create(HttpStatusCode.InternalServerError, "Error Date Not Fetch", exp.Message));
            }
        }
}

我从Stackoverflow的控制器中删除了其他操作/方法

signal-r.service.ts

import { Injectable } from '@angular/core';
import * as signalR from "@aspnet/signalr";
import { HttpClient } from '@angular/common/http';
@Injectable({
  providedIn: 'root'
})

export class SignalRService {
  public data: VehicleModel[]
  private hubConnection: signalR.HubConnection
  options: signalR.IHttpConnectionOptions = {
    accessTokenFactory: () => {
     let token = localStorage.getItem("token")
      return `Bearer ${token}`;
    },
  };
  public startConnection = () => {
    this.hubConnection = new signalR.HubConnectionBuilder()
                            .withUrl('http://localhost:50915/Utility/GetAllVehicles', this.options)
                            .build();

    this.hubConnection
      .start()
      .then(() => console.log('Connection started'))
      .catch(err => console.log('Error while starting connection: ' + err))
  }

  public addTransferChartDataListener = () => {
    this.hubConnection.on('transferchartdata', (data) => {
      this.data = data;
      console.log(data);
    });
  }
  constructor() { }
}

export interface VehicleModel {
  id : any
  name : any
  vehicleType : any
  modelNo : any
  registrationNo : any
  lcsVehicleNo : any
  relationShipOfficerId : any
  driverId : any
  driverName : any
  relationShipOfficerName : any
  isActive : any
  createdOn : any
  createdBy : any
  modifiedOn : any
  modifyBy : any
  locationId : any
  createdById : any
  modifyById : any
}

App.component.ts

 ngOnInit() {
    this.signalRService.startConnection();
    this.signalRService.addTransferChartDataListener();   
    this.startHttpRequest();
}

我已从App.component中删除了Stackoverflow的其他方法

signal的nuget包

my nuget package for signalr

Signar的角度版本

my angular version for sinalr

我在浏览器控制台中收到此错误,但是当我在控制器上添加断点时,它仅一次完美地执行了该操作(您可以在控制台中看到响应)

error in browser console

下面是首次使用的GetAllVehicle的网络快照

network snapshot for GetAllVehicles that works

下面是具有CORS问题的协商网络快照

network snapshot for negotiate that have CORS issue我也尝试过this url,但一无所获。

angular .net-core cors signalr
1个回答
0
投票

您需要在中心上添加CORS,例如:

关于配置方法

app.UseCors(CorsPolicy);

关于AddAditionalServices

services.AddCors(options =>
{
    options.AddPolicy(CorsPolicy, builder => builder.WithOrigins("http://localhost:4200")
        .AllowAnyHeader()
        .AllowAnyMethod()
        .AllowCredentials()
        .SetIsOriginAllowed((host) => true));
});

请注意,CORS方法的顺序很重要!

也不要使用@aspnet/signalr程序包,因为它已被放弃并且已过时。您应该使用新的@microsoft/signalr程序包,它还为您提供AutomaticReconnect功能。

© www.soinside.com 2019 - 2024. All rights reserved.