Web Api 2 Preflight CORS 请求承载令牌

Posted

技术标签:

【中文标题】Web Api 2 Preflight CORS 请求承载令牌【英文标题】:Web Api 2 Preflight CORS request for Bearer Token 【发布时间】:2015-01-14 19:29:50 【问题描述】:

我有一个带有 AngularJS 前端和 Web Api 2 后端的网络应用程序,它使用不记名令牌进行身份验证。

在 FireFox 和 IE 中一切正常,但在 Chrome 中,我的初始登录请求有时会预先进行。

这是来自 AngularJS 服务的调用:

$http.post(http://localhost:55483/token, data, headers: 'Content-Type': 'application/x-www-form-urlencoded' ).success(function (response) ... );

预检请求因“Allow-Access-Control-Origin”错误而被退回。

但是,如果我再次单击登录按钮(从而重新发送上述请求),一切都很好。

关于如何预防/诱捕/处理此问题的任何想法?

PS:我用的是 LOC

context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[]  "*" );

ApplicationOAuthProvider.cs 文件中将 CORS 允许标头放在 /Token 请求中,这在 IE、FireFox 和有时在 Chrome 中运行良好。

【问题讨论】:

您是否在启动时为webapi 添加了allowcors 你的意思是这个 LOC:app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);我试图把它放进去,但编译器说:Owin.IAppBuilder'不包含'UseCors'的定义 是的,它看起来很相似,但您可能需要包含一些用于 cors 的 nuget 包 在 6 月 29 日 LeftyX 的帖子的帮助下解决了这个问题:移动这个 LOC app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);到 Startup.Auth.cs 的 ConfigureAuth 方法中的第一行。然后,删除这个 LOC context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] "*" );来自 ApplicationOAuthProvide.cs 的 GrantResourceOwnerCredentials() 方法。预检 CORS 请求它们得到正确处理,然后实际请求通过。 @FancyNancy 感谢 FancyNancy 的评论!你能把你的评论作为这个问题的答案吗?您的评论是唯一对我有用的答案!我相信其他人会很感激指定的答案。 【参考方案1】:

以下是花式评论:

在 6 月 29 日 LeftyX 的帖子的帮助下解决了这个问题: - 移动 此 LOC app.UseCors(Microsoft.Owin.Cors.CorsOptions.AllowAll);Startup.Auth.csConfigureAuth 方法中的第一行。 - 那么, 删除此 LOC context.OwinContext.Response.Headers.Add("Access-Control-Allow-Origin", new[] "*" ); 来自 GrantResourceOwnerCredentials() 方法 ApplicationOAuthProvide.cs。 预检 CORS-请求他们获取 处理得当,然后实际requet通过

谢谢你,你救了我一整天。 因为它发生在很多人身上,我把你的评论带到答案框,让其他人可以看到。 我不想为此投票。请改为评论我的答案 谢谢

【讨论】:

感谢 Fancy 发布这个答案,这是我的问题,我在多个地方设置了 cors 选项。 在第2步,您可以使用context.OwinContext.Response.Headers.SetValues("Access-Control-Allow-Origin", allowedOriginStr);重写header【参考方案2】:

我希望这能够帮助那里的人。对我来说:

添加 app.useCors(); LOC 无效。 添加 app.useCors(); LOC 对我团队中的其他人有用。

所以我需要一个适用于所有人环境的解决方案。

我最终做的是将标题和值添加到 Web.config 中,并带有以下 (其中 localhost:9000 是我的节点应用程序,它正在提供 angular):

<system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Access-Control-Allow-Origin" value="http://localhost:9000" />
        <add name="Access-Control-Allow-Headers" value="Content-Type"/>
      </customHeaders>
    </httpProtocol>
  </system.webServer>

然后在生产中,您只需将源值更改为生产前端 url。

如果您希望为所有来源启用 CORS,请将值更改为 "*"

【讨论】:

尽管出于显而易见的原因,我会告诫不要为所有来源启用 CORS。 这是最好的答案!现在,只需为不同的环境设置 Web 部署转换即可。 @TheCee 没错。就我而言,我设置了一个 Web.config.staging 和一个 Web.config.production【参考方案3】:

默认情况下 - Access-Control-Max-Age: seconds 为 0 并且您的请求不缓存。

尝试将其设置为最大值:(Owin selfhost)。它解决了额外的 OPTIONS 请求问题

            app.UseCors(new CorsOptions
            
                PolicyProvider = new CorsPolicyProvider
                
                    PolicyResolver = context => Task.FromResult(new CorsPolicy
                    
                        AllowAnyHeader = true,
                        AllowAnyMethod = true,
                        AllowAnyOrigin = true,
                        SupportsCredentials = false,
                        PreflightMaxAge = Int32.MaxValue // << ---- THIS
                    )
                
            );

【讨论】:

【参考方案4】:

让我补充一件我今天学到的东西。此示例:

app.UseCors(CorsOptions.AllowAll);

从一开始就为我工作。我只是不知道,因为我一直在做验证的请求没有以下标题:

Origin: http://hostname
Access-Control-Request-Method: GET

只有在我添加了这些之后,正确的标题才开始出现在响应中。

【讨论】:

以上是关于Web Api 2 Preflight CORS 请求承载令牌的主要内容,如果未能解决你的问题,请参考以下文章

使用具有多个来源的 PUT 和 DELETE 请求时如何解决 ASP.NET Web API CORS Preflight 问题?

Axios CORS/Preflight 因 Laravel 5.4 API 调用而失败

已解决 - CORS、OPTIONS 和 PreFlight 问题 在 Vue.js 中使用 Axios 使用 REST API

对 CORS preflight OPTIONS 请求的响应是 Laravel API 中的 500 Internal Server Error

Angular 的 Spring Cloud Gateway Preflight Cors 错误

CORS Preflight 403,但我有正确的标题