当提供商因缺少授权标头而拒绝飞行前请求时,使客户端CORS正常工作

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了当提供商因缺少授权标头而拒绝飞行前请求时,使客户端CORS正常工作相关的知识,希望对你有一定的参考价值。

我正在开发一个Angular应用程序,它将消耗SalesForce API(a.k.a.一个SalesForce“Connected App”)。身份验证通过oAuth / OpenID进行,效果很好。但是,该应用程序当前无法成功访问SalesForce API端点,因为:

  1. 它是一个无服务器的应用程序,REST调用是客户端,AND
  2. REST调用是“非简单的”:它们包括自定义标头(即保存oAuth访问令牌的“授权”标头),从而导致浏览器发出飞行前OPTIONS请求;和
  3. SalesForce拒绝任何不包含有效“授权”标头和令牌的API请求,包括飞行前,根据定义,它不包括初始GET请求中的自定义标头(实际上,飞行前的整个点是询问服务器是否允许有问题的自定义标头)。

客户端应用程序URL已添加到SalesForce设置中的CORS原始白名单,无效。

这让我完全陷入困境。我无法通过从REST调用中删除自定义“授权”标头来避免飞行前,因为然后将oAuth令牌传输到端点的唯一方法是在URL参数中,这是不安全的;我不能通过我自己的后端代理请求(即,避免前端CORS限制),因为它是一个无服务器的应用程序;而且我无法让SalesForce接受飞行前的准备,因为它完全受浏览器控制,并且无法修改其标题。

有没有办法配置或强制SalesForce接受没有“授权”标题的飞行前OPTIONS请求?如果没有,可能还有其他方式让我摆脱这个捕获22?

以下是示例代码:

XHR请求:

{
  "url": "https://test.salesforce.com/services/oauth2/userinfo",
  "body": null,
  "reportProgress": false,
  "withCredentials": false,
  "responseType": "json",
  "method": "GET",
  "headers": {
    "normalizedNames": [
      {
        "key": "accept",
        "value": "Accept"
      },
      {
        "key": "authorization",
        "value": "Authorization"
      }
    ],
    "lazyUpdate": null,
    "headers": [
      {
        "key": "accept",
        "value": ["application/json"]
      },
      {
        "key": "authorization",
        "value": ["Bearer [...]"] // OAuth token is here
      }
    ],
    "lazyInit": null
  },
  "params": {
    "updates": null,
    "cloneFrom": null,
    "encoder": { HttpUrlEncodingCodec },
    "map": null
  },
  "urlWithParams": "https://test.salesforce.com/services/oauth2/userinfo"
}

由以上原因导致的test.salesforce.com:443飞行前请求:

OPTIONS /services/oauth2/userinfo HTTP/1.1
Host: test.salesforce.com
Connection: close
Pragma: no-cache
Cache-Control: no-cache
Access-Control-Request-Method: GET
Origin: [...] // client app URL is here
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_2) AppleWebKit/537.36 (Khtml, like Gecko) Chrome/63.0.3239.84 Safari/537.36
Access-Control-Request-Headers: authorization
Accept: */*
DNT: 1
Accept-Encoding: gzip, deflate
Accept-Language: en-US,en;q=0.9

对飞行前请求的回应:

HTTP/1.1 403 Forbidden
Date: Fri, 22 Dec 2017 20:16:11 GMT
Strict-Transport-Security: max-age=31536000; includeSubDomains
X-Content-Type-Options: nosniff
X-XSS-Protection: 1; mode=block
Content-Security-Policy: upgrade-insecure-requests 
Referrer-Policy: origin-when-cross-origin
Cache-Control: no-cache,must-revalidate,max-age=0,no-store,private
Set-Cookie: BrowserId=IBrO4jKqQ6qedsWA5DFIcw;Path=/;Domain=.salesforce.com;Expires=Tue, 20-Feb-2018 20:16:11 GMT;Max-Age=5184000
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Connection: close
Content-Length: 19

Missing_OAuth_Token

非常感谢提前!

P.S:这是我在StackOverflow上发布的第一个问题。我希望它符合标准。如果不是我提前道歉,我会很乐意修改。

答案

我怀疑你还在忙着开发这个应用程序,请求来自localhost

还不确定你是否已经看过对飞行前的实际响应是什么,以及Access-Control-Allow-Methods是否包括你试图调用的PUT或GET方法?

如果正确设置,Salesforce绝对支持CORS。

在Salesforce安装程序中,您可以将源列入白名单以进行跨源资源共享(CORS),然后可以允许该源执行在Web浏览器中运行的代码(例如javascript)以与Salesforce进行通信。

有关此主题的更多信息,请参阅Salesforce文档:

https://developer.salesforce.com/docs/atlas.en-us.chatterapi.meta/chatterapi/extend_code_cors.htm

以上是关于当提供商因缺少授权标头而拒绝飞行前请求时,使客户端CORS正常工作的主要内容,如果未能解决你的问题,请参考以下文章

AugularJS 中的飞行前 OPTIONS 请求未通过授权标头

如果通过 Zuul API 网关发送请求,则缺少授权标头

使用 WCF 的 Http 请求中缺少授权标头

POST请求中缺少授权标头[重复]

如何从 Web 服务提供飞行前请求

我们应该在发送响应时关闭飞行前 Cors 请求的连接吗?