ASP.NET Core Web API + Angular 对预检请求的响应未通过访问控制检查:预检请求不允许重定向

Posted

技术标签:

【中文标题】ASP.NET Core Web API + Angular 对预检请求的响应未通过访问控制检查:预检请求不允许重定向【英文标题】:ASP.NET Core Web API + Angular Response to preflight request doesn't pass access control check: Redirect is not allowed for a preflight request 【发布时间】:2020-10-15 19:26:22 【问题描述】:

我在 ASP.NET Core Web API 上有一个后端,在 Angular 9 上有一个前端。我正在实施 google 身份验证。在邮递员中它工作正常,但在我的角度应用程序中,当我尝试通过谷歌授权时出现错误:

Access to XMLHttpRequest at 'https://accounts.google.com/o/oauth2/v2/... 
(redirected from 'https://localhost:44340/api/auth/googlelogin')
from origin 'http://localhost:4200' has been blocked by CORS policy: 
Response to preflight request doesn't pass access control check:
Redirect is not allowed for a preflight request.

后端的CORS配置:

            services.AddCors(options =>
            
                options.AddPolicy("MyPolicy",
                      builder =>
                      
                          builder
                          .WithOrigins(Configuration["ApplicationSettings:Client_URL"].ToString())
                          .AllowAnyOrigin()
                          .AllowAnyHeader()
                          .AllowAnyMethod();
                      );
            );
            app.UseCors("MyPolicy");

我的服务中的方法

        public ChallengeResult LoginViaGoogle()
        
            var provider = "Google";
            var redirectUrl = "/api/auth/ExternalLoginCallBack";
            var properties = Database.SignInManager.ConfigureExternalAuthenticationProperties(provider, redirectUrl);
            return new ChallengeResult(provider, properties);
        

我的控制器中的方法

        [HttpGet("GoogleLogin")]
        public IActionResult GoogleLogin()
        
            ChallengeResult result;
            try
            
                result = _authService.LoginViaGoogle();
            
            catch(Exception ex)
            
                throw ex;
            
            return result;
        

我在 Angular 中的方法:

  googleLogin()
    const httpOptions = 
      headers: new HttpHeaders(
        "Access-Control-Allow-Origin": "*"
      )
    ;
    return this.http.get("https://localhost:44340/api/auth/googlelogin", httpOptions);
  

我在这个网站上尝试了很多解决方案,但都没有帮助。

我认为问题可能是我在 google oauth 中错误地注册了 URL。

【问题讨论】:

你的 appconfig 文件中 Client_URL 的值是多少? @bthn http://localhost:4200,除了谷歌身份验证,一切正常。 我认为 google 无法向您的本地主机发送请求。您应该购买或使用免费域并托管您的应用程序并将该域提供给 google。 我不确定,但也许你也可以尝试使用 ngrok 让 google auth 与 localhost 一起工作。 @bthn 但如果我在浏览器或邮递员中访问我的 api uri https://localhost:44340/api/auth/googlelogin 我可以授权并获取令牌,所以我认为问题与本地主机无关。 【参考方案1】:

问题是您在此获取请求上返回了重定向,即not allowed when using CORS。

如果您遇到此类问题,我绝对会建议您查看 MDN 文档,它们非常有用且几乎完整。

要解决此问题,您可以返回带有正确身份验证 URL 的有效负载,然后使用您的前端代码进行跟踪。

我不特别了解角度,但我想它看起来像:

googleLogin()
  // This header options was not doing anything, the request cannot tell the server how to do CORS.
  const authUrl = this.http.get("https://localhost:44340/api/auth/googlelogin");
  return this.http.get(authUrl);

【讨论】:

如果我不使用标题选项,我会收到另一个错误:... has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header is present on the requested resource. 而在角度上不可能写return this.http.get(authUrl);,我只能return authUrl; 显然 Angular 会自动调用 CORS,因此标题绝对应该什么都不做。您在构建器上的 WithOrigins 函数可能会覆盖您的 AllowsAnyOrigin,这可能会导致问题。也许先尝试使用正常的有效载荷,然后从那里开始。重定向可能会抛出红鲱鱼。 首先正常有效载荷是什么意思? 您可以在没有正文的情况下进行 POST,因为这是一个更改状态(登录)的端点,您将希望使用 POST,因为 GET 旨在获取信息而不是更改状态.如果您将 Angular 更改为 .post 并将方法更改为 [HttpPost()] 它现在将是一个 post 方法...至于重定向,返回带有 url 的有效负载仍然可能是您的最佳选择,那么您可以使用 angular 来关注它并且不会存在 CORS 重定向问题。【参考方案2】:

当您对后端进行 ajax 调用并将重定向返回给 Google 时,您的初始请求将遵循该重定向。这意味着您正在尝试对 Google 进行 ajax 调用,这是不允许的。

为了解决这个问题,您需要通过一些表单提交或执行window.location='yourdomain.page/path' 对您的后端进行实际的、完整的“回发”。这就是为什么当您将 url 放到浏览器中并按 Enter 时有效的原因。

我的建议是让端点只返回您可以使用 ajax 访问的 google oauth url,然后进行重定向,即

const url = await httpClient.get<GoogleAuth>('/oauth/google').toPromise(); //replace with your google auth returning endpoint
window.location = url;

【讨论】:

什么是&lt;GoogleAuth&gt;? Angular 没有这种东西 这只是一个示例类,将其替换为您的端点返回并可以反序列化的任何内容。

以上是关于ASP.NET Core Web API + Angular 对预检请求的响应未通过访问控制检查:预检请求不允许重定向的主要内容,如果未能解决你的问题,请参考以下文章

ASP.NET Core Web Api 自动帮助页面

ASP.NET Core Web API

Asp.Net Core 1.1 消费web api

使用 ASP.NET Core MVC 创建 Web API

如何从 ASP.NET MVC 到 ASP.NET Core Web API 的 PUT?

ASP.NET Web API 与 ASP.NET Core 中的 URL 匹配差异