Azure Functions:CORS:如何在飞行前支持“Access-Control-Allow-Credentials”标头和选项?

Posted

技术标签:

【中文标题】Azure Functions:CORS:如何在飞行前支持“Access-Control-Allow-Credentials”标头和选项?【英文标题】:Azure Functions: CORS: How to support "Access-Control-Allow-Credentials" header AND OPTIONS pre-flight? 【发布时间】:2017-06-13 13:16:23 【问题描述】:

已编辑

因为 *** 不喜欢你删除东西。这是我自己的愚蠢。

我学到了什么:

OPTIONS 方法目前似乎不适用于 Azure 在本地运行 Azure 函数时的函数 Cli。 I created a GitHub Issue for this。 Azure 上的 Azure Functions 支持 OPTIONS 请求,非常好用。当您在通过代理手动测试时搞砸并在请求的 HOST 中有错误的标头时,他们只是不明白:-P。

我有一个 Azure 函数,它需要 cookie 来携带会话详细信息。因此,我需要将标题“Access-Control-Allow-Credentials”设置为 true。

此处详述: https://github.com/Azure/azure-webjobs-sdk-script/issues/620

如果您通过删除所有 CORS url 来禁用函数应用程序的默认“应用程序服务”CORS 设置,它将允许您设置与 CORS 相关的标头,例如“Access-Control-Allow-Credentials”。这很好用。

但是,禁用 CORS 设置后,您需要手动处理所有 CORS 功能。问题在于 Azure 函数似乎不允许您在定义函数时使用 OPTIONS 动词。因此,似乎没有办法处理 CORS Pre-Flight 请求。

有什么推荐的解决方法吗?

仅供参考,这是我的 function.json:


  "disabled":false,
  "bindings":[
    
      "name": "req",
      "type": "httpTrigger",
      "direction": "in",
      "authLevel": "anonymous",
      "methods": [ "OPTIONS" ],
      "route": "1.0/myFunction"
    ,
    
      "name": "res",
      "type": "http",
      "direction": "out"
    
  ]

这是代码:

'use strict';

module.exports = function(context, req)
    var shared = require('../auth-shared-libraries');
    var cors_url = shared.getCORSUrl(context);
    context.res = 
        status: 200,
        headers: 
            "Access-Control-Allow-Credentials" : "true",
            "Access-Control-Allow-Origin" : cors_url,
            "Access-Control-Allow-Methods" : "POST, OPTIONS",
            "Access-Control-Allow-Headers" : "Content-Type, Set-Cookie",
            "Access-Control-Max-Age" : "86400",
            "Vary" : "Accept-Encoding, Origin",
            "Content-Type" : "application/json"
        ,
        body : JSON.stringify(req)
    ;
    context.done();

这是发送给它的示例请求:

OPTIONS /api/1.0/myFunction HTTP/1.1
Host: localhost:7071
User-Agent: Mozilla/5.0 (Windows NT 10.0; WOW64; rv:51.0) Gecko/20100101 Firefox/51.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Access-Control-Request-Method: POST
Origin: http://localhost:9000
Connection: close

如果我针对托管在 Azure 上的 Azure-Function 运行它,这是我得到的响应:

HTTP/1.1 404 Site Not Found
Content-Type: text/html
Server: Microsoft-IIS/8.0
Date: Tue, 14 Feb 2017 01:57:14 GMT
Connection: close
Content-Length: 5147

<!DOCTYPE html>
<html>
<head>
    <title>Microsoft Azure Web App - Error 404</title>
    <style type="text/css">
        html 
            height: 100%;
            width: 100%;
        

        #feature 
            width: 960px;
            margin: 75px auto 0 auto;
            overflow: auto;
        

        #content 
            font-family: "Segoe UI";
            font-weight: normal;
            font-size: 22px;
            color: #ffffff;
            float: left;
            width: 460px;
            margin-top: 68px;
            margin-left: 0px;
            vertical-align: middle;
        

            #content h1 
                font-family: "Segoe UI Light";
                color: #ffffff;
                font-weight: normal;
                font-size: 60px;
                line-height: 48pt;
                width: 800px;
            

        p a, p a:visited, p a:active, p a:hover 
            color: #ffffff;
        

        #content a.button 
            background: #0DBCF2;
            border: 1px solid #FFFFFF;
            color: #FFFFFF;
            display: inline-block;
            font-family: Segoe UI;
            font-size: 24px;
            line-height: 46px;
            margin-top: 10px;
            padding: 0 15px 3px;
            text-decoration: none;
        

            #content a.button img 
                float: right;
                padding: 10px 0 0 15px;
            

            #content a.button:hover 
                background: #1C75BC;
                    
    </style>
    <script type="text/javascript">
        function toggle_visibility(id) 
            var e = document.getElementById(id);
            if (e.style.display == 'block')
                e.style.display = 'none';
            else
                e.style.display = 'block';
        
    </script>
</head>
<body bgcolor="#00abec">
    <div id="feature">
        <div id="content">
            <h1>Error 404 - Web app not found.</h1>
            <p>The web app you have attempted to reach is not available in this Microsoft Azure App Service region. This could be due to one of several reasons:
            <p>
                1. The web app owner has registered a custom domain to point to the Microsoft Azure App Service, but has not yet configured Azure to recognize it. <a href="#" onclick="toggle_visibility('moreone');">Click here to read more</a></abbr>.
                <div id="moreone" style="display:none">
                    <font size=2>
                      When an app owner wants to use a custom domain with a <a href="http://www.windowsazure.com/en-us/services/web-sites/">Microsoft Azure Web Apps</a> web app, Azure needs to be configured to recognize the custom domain name, so that it can route the request to the appropriate server in the region. After registering the domain with a domain provider and configuring a DNS CNAME record to point to the app&#39;s Azurewebsites.net address (for example, contoso.azurewebsites.net), the web app owner also needs to go to the Azure Portal and configure the app for the new domain. <a href="http://www.windowsazure.com/en-us/documentation/articles/web-sites-custom-domain-name/">Click here</a> to learn more about configuring the custom domains for a web app.
                     </font>
</div>
        <p>
          2. The web app owner has moved the web app to a different region, but the DNS cache is still directing to the old IP Address that was used in the previous region. <a href="#" onclick="toggle_visibility('moretwo');">Click here to read more.</a>
            <div id="moretwo" style="display:none">
                <font size=2>
                    With <a href="http://www.windowsazure.com/en-us/services/web-sites/">Web Apps</a>, the app is stored in a datacenter located in the region that the web app owner has selected when creating the app, and Azure�s DNS server resolves the web app address that was chosen for it to that datacenter. DNS servers are in charge of resolving the name of the server the user is trying to reach into an IP address, but clients cache this information in order to be able to load the page as fast as possible. If this app was deleted and re-created in another region, the new app will have a different IP address, but the client might still be caching the old IP address.

                    First, try clearing the cache on your client <a href="http://technet.microsoft.com/en-us/library/cc781949(v=ws.10).aspx">as described here</a>. If this does not help, this is probably due to the caching done on an intermediate DNS server such as the one used by your Internet Service Provider. If so, this issue should clear up soon, once the DNS cache reaches its time-to-live period. Please try to visit the app again in approximately one hour. If you continue to receive this error page, please contact <a href="http://www.windowsazure.com/en-us/support/options/">Microsoft support</a>.
                    </font>
            </div>
        </div>
     </div>
</body>
</html>

这是我对本地运行的 Azure-Functions-Cli 运行请求时得到的响应:

注意:它抱怨 Origin,但我不知道用于设置 CORS 的本地开发的配置。如果有,我不确定当这似乎需要手动操作时如何将其转化为 Azure。

HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
Server: Microsoft-HTTPAPI/2.0
Date: Tue, 14 Feb 2017 01:28:12 GMT
Connection: close
Content-Length: 64

"Message":"The origin 'http://localhost:9000' is not allowed."

【问题讨论】:

【参考方案1】:

我对使用 OPTIONS 动词没有意见。

您能否确保您的 function.json 在“方法”数组中包含“选项”,如下所示:


  "bindings": [
    
      "authLevel": "anonymous",
      "name": "req",
      "type": "httpTrigger",
      "direction": "in",
      "methods": ["get", "post", "options"]
    
  ]

或者,您可以完全删除“方法”数组并允许所有方法。

【讨论】:

我不知道你为什么没有这个问题。我只是再次重试了所有内容,但在部署到 Azure 选项时仍然出现 404,使用 Azure-Functions-Cli“func run myFunction”时出现 400 错误。我已经发布了更多详细信息。 让我收回。向 Azure 发送请求时,我没有更新“主机”标头。它确实显示 OPTIONS 在 Azure 上工作,只是在 Azure-Functions-CLI 上失败【参考方案2】:

如果您在本地运行时遇到问题,请添加:

  "Host": 
    "CORS": "*"
  

到local.settings.json

【讨论】:

我觉得只有在本地开发的时候才需要这个。对于实际生产,不要在函数中添加OPTIONS方法,正确定义CORS;它应该工作。设置 OPTIONS 为方法,本地测试时直接调用函数;不过对生产不太确定。 谢谢,我在本地运行 azure 函数时遇到问题,因为 chrome 使 OPTIONS 请求寻找失败的 CORS。这就是整理它所需的全部内容。

以上是关于Azure Functions:CORS:如何在飞行前支持“Access-Control-Allow-Credentials”标头和选项?的主要内容,如果未能解决你的问题,请参考以下文章

调用 Azure Functions 的静态 Angular 应用程序。是安全问题吗?

在 Azure Functions 中配置 Access-Control-Allow-Headers

如何从 Azure 移动应用服务调用 HTTP(Azure Functions)?

Azure Functions:如何在 Azure 存储队列的绑定表达式中使用 POCO?

如何使用应用服务对 Azure Functions 应用进行身份验证/授权?

如何使用 Azure Functions 检查授权