web-dev-qa-db-ja.com

Azure関数:CORS:「Access-Control-Allow-Credentials」ヘッダーとオプションのプリフライトをサポートする方法は?

編集済み

StackOverflowはあなたが物を削除するのを好まないので。これは私自身の愚かさでした。

私が学んだこと:

  • 現在、Azure関数をローカルで実行している場合、OPTIONSメソッドはAzure FunctionsCliで機能しないようです。
  • Azure上のAzureFunctionsは、OPTIONS要求を問題なくサポートします。プロキシを介して手動でテストするときに、混乱してリクエストのホストに間違ったヘッダーがあると、彼らはそれを理解しません:-P。

セッションの詳細を運ぶためにCookieを必要とするAzure関数があります。その結果、ヘッダー「Access-Control-Allow-Credentials」をtrueに設定する必要があります。

ここで詳しく説明されているように: https://github.com/Azure/azure-webjobs-sdk-script/issues/62

すべてのCORSURLを削除してFunctionAppのデフォルトの「AppServices」CORS設定を無効にすると、「Access-Control-Allow-Credentials」などのCORS関連のヘッダーを設定できるようになります。これは美しく機能します。

ただし、CORS設定を無効にすると、すべてのCORS機能を手動で処理する必要があります。これに伴う問題は、Azure関数では、関数を定義するときにOPTIONS動詞を使用できないように見えることです。その結果、CORSプリフライトリクエストを処理する方法がないようです。

推奨される回避策はありますか?

参考までに、これは私の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でホストされている関数に対して実行した場合に得られる応答です。

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に対してリクエストを実行した場合に得られる応答です。

注:オリジンについて文句を言いますが、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."}
9
Doug

OPTIONS動詞の使用に問題はありません。

次のように、function.jsonの「methods」配列に「options」が含まれていることを確認できますか?

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

または、「methods」配列を完全に削除して、すべてのメソッドを許可することもできます。

3
Matt Mason

これをローカルで実行するのに問題がある場合は、以下を追加してください。

  "Host": {
    "CORS": "*"
  }

Local.settings.jsonへ

5
Mister Cook