.NET Core webapp 服务 SPA:被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头
Posted
技术标签:
【中文标题】.NET Core webapp 服务 SPA:被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头【英文标题】:.NET Core webapp serving SPA: Blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource 【发布时间】:2020-01-28 20:35:24 【问题描述】:最基本的问题是这样的:
如果来自浏览器的常规 GET 或来自 Postman 的常规 GET 请求,我的“/api/users/githublogin”端点工作正常。但是,XHR、fetch 和 axios 都抛出同样的错误:
CORS 策略已阻止从源“https://localhost:5001”在“https://github.com/login/oauth/authorize?etc”(从“https://localhost:5001/api/users/githublogin”重定向)获取的访问权限:没有“Access-Control-Allow-Origin”标头出现在请求的资源。如果不透明的响应满足您的需求,请将请求的模式设置为“no-cors”以获取禁用 CORS 的资源。
有几个相关的问题,与 Angular 相关的比 React 更多,但问题似乎相同:
Enable CORS in ASP .NET Core 2.1 Web Api
No 'Access-Control-Allow-Origin' header is present. XmlHttpRequest
.NET CORE 2.0 Angular 5: Allowing Cors
Local javascript Fetch Post Request Fails with call to ASP.NET Core 2.2 Web API. CORS is enabaled
我已经实施了他们的答案,但没有成功。
以下是关于 CORS 策略的服务器端代码:
在 ConfigureServices 方法中:
services.AddCors();
在 Configure 方法中:
app.UseCors(x => x
.AllowAnyHeader()
.AllowAnyMethod()
.AllowAnyOrigin()
.AllowCredentials());
在我的客户端,一个按钮调用此代码:
fetch('/api/users/githublogin');
以下是发出失败请求时的服务器日志:
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[1]
Request starting HTTP/1.1 GET https://localhost:5001/api/users/githublogin application/json
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request starting HTTP/1.1 GET https://localhost:5001/api/users/githublogin application/json
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[0]
Executing endpoint 'web_server.Controllers.UsersController.GitHubLogin (web-server)'
Microsoft.AspNetCore.Routing.EndpointMiddleware:Information: Executing endpoint 'web_server.Controllers.UsersController.GitHubLogin (web-server)'
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[3]
Route matched with action = "GitHubLogin", controller = "Users". Executing controller action with signature Microsoft.AspNetCore.Mvc.ActionResult GitHubLogin(System.String) on controller web_server.Controllers.UsersController (web-server).
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Route matched with action = "GitHubLogin", controller = "Users". Executing controller action with signature Microsoft.AspNetCore.Mvc.ActionResult GitHubLogin(System.String) on controller web_server.Controllers.UsersController (web-server).
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[1]
Executing action method web_server.Controllers.UsersController.GitHubLogin (web-server) - Validation state: Valid
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executing action method web_server.Controllers.UsersController.GitHubLogin (web-server) - Validation state: Valid
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action method web_server.Controllers.UsersController.GitHubLogin (web-server), returned result Microsoft.AspNetCore.Mvc.ChallengeResult in 0.7161ms.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
Executed action method web_server.Controllers.UsersController.GitHubLogin (web-server), returned result Microsoft.AspNetCore.Mvc.ChallengeResult in 0.7161ms.
info: Microsoft.AspNetCore.Mvc.ChallengeResult[1]
Executing ChallengeResult with authentication schemes ().
Microsoft.AspNetCore.Mvc.ChallengeResult:Information: Executing ChallengeResult with authentication schemes ().
info: Microsoft.AspNetCore.Authentication.OAuth.OAuthHandler`1[[Microsoft.AspNetCore.Authentication.OAuth.OAuthOptions, Microsoft.AspNetCore.Authentication.OAuth, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]][12]
AuthenticationScheme: GitHub was challenged.
Microsoft.AspNetCore.Authentication.OAuth.OAuthHandler`1[[Microsoft.AspNetCore.Authentication.OAuth.OAuthOptions, Microsoft.AspNetCore.Authentication.OAuth, Version=2.2.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]]:Information: AuthenticationScheme: GitHub was challenged.
info: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker[2]
Executed action web_server.Controllers.UsersController.GitHubLogin (web-server) in 76.0766ms
info: Microsoft.AspNetCore.Routing.EndpointMiddleware[1]
Executed endpoint 'web_server.Controllers.UsersController.GitHubLogin (web-server)'
Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker:Information: Executed action web_server.Controllers.UsersController.GitHubLogin (web-server) in 76.0766ms
Microsoft.AspNetCore.Routing.EndpointMiddleware:Information: Executed endpoint 'web_server.Controllers.UsersController.GitHubLogin (web-server)'
info: Microsoft.AspNetCore.Hosting.Internal.WebHost[2]
Microsoft.AspNetCore.Hosting.Internal.WebHost:Information: Request finished in 145.364ms 302
Request finished in 145.364ms 302
与 CORS 无关。事实上在整个服务器日志中只有这么多提到它:
warn: Microsoft.AspNetCore.Cors.Infrastructure.CorsService[11]
The CORS protocol does not allow specifying a wildcard (any) origin and credentials at the same time. Configure the policy by listing individual origins if credentials needs to be supported.
Microsoft.AspNetCore.Cors.Infrastructure.CorsService:Warning: The CORS protocol does not allow specifying a wildcard (any) origin and credentials at the same time. Configure the policy by listing individual origins if credentials needs to be supported.
info: Microsoft.AspNetCore.Cors.Infrastructure.CorsService[4]
CORS policy execution successful.
Microsoft.AspNetCore.Cors.Infrastructure.CorsService:Information: CORS policy execution successful.
现在,在我看来,我的服务器似乎正在正确执行它应该执行的操作。那 302 Found (如果我没记错的话)基本上是一个信号给客户端重定向到那个 github 端点。因此,如果我的服务器没有向请求抛出与 CORS 相关的异常(或者它确实有效),并且实际上设置了 AllowAnyOrigins 标志,那么为什么客户端会收到此错误?以及为什么浏览器发出GET请求时收不到呢?
我应该注意到这是一个开发服务器。正如文档所鼓励的那样,我正在使用 spa.UseProxyToSpaDevelopmentServer("http://localhost:3000");
选项。这是我能想象到的一件事让我感到困惑,因为从技术上讲,请求来自跨域(从端口:3000 到端口:5001),但我相信考虑到 AllowAnyOrigins 标志,这应该不是问题。
该 api 是从一个基本的 ASP.NET Core 2.2 webapi 模板构建的。客户端是使用 create-react-app 构建的。他们都是非常样板。
任何人都可以帮助阐明这些吗?
【问题讨论】:
【参考方案1】:以下是关于 CORS 策略的服务器端代码...
这无关紧要,因为您正在向 GitHub 服务器发出请求。 GitHub 的服务器策略是这里唯一相关的,你无法控制它。
如果来自浏览器的常规 GET 或来自 Postman 的常规 GET 请求,我的“/api/users/githublogin”端点工作正常。
正确,这是因为您拥有 '/api/users/githublogin',而您不拥有 https://github.com/login/oauth/authorize?etc。
而且 CORS 确实被 GitHub 设计锁定了:https://github.com/isaacs/github/issues/330
解决方案:
由于 CORS 仅在浏览器范围内发挥作用,因此重新设计您的架构并实现您自己的服务器端 Web 代理,以便对 GitHub 的调用进行 服务器端;不是浏览器中的客户端。这里有更多关于 CORS 的资源:
https://medium.com/@baphemot/understanding-cors-18ad6b478e2b https://www.sitepoint.com/working-around-origin-policy/ Creating a proxy to another web api with Asp.net core【讨论】:
非常感谢。一旦我在帖子中列出了所有内容,我就明白了这一点,但由于我直到那时我才将它留给问题+答案的潜在价值。也就是说,我的问题被否决是有原因的吗? @jbarreto93:不。我会用赞成票取消它。以上是关于.NET Core webapp 服务 SPA:被 CORS 策略阻止:请求的资源上不存在“Access-Control-Allow-Origin”标头的主要内容,如果未能解决你的问题,请参考以下文章
ASP.Net Core 6,SPA,端点 - 我无法从 http get 请求调用控制器
单页应用 WebApp SPA 骨架 框架 路由 页面切换 转场
在 IIS 上托管的 ASP.NET Core WebApp 上提供持久配置
SignalR 授权无法在带有 Identity Server 的 asp.net core angular SPA 中开箱即用