Azure Functions HTTP 트리거

HTTP 트리거를 사용하면 HTTP 요청으로 함수를 호출할 수 있습니다. HTTP 트리거를 사용하여 서버리스 API를 만들고 웹후크에 응답할 수 있습니다.

HTTP 트리거 함수의 기본 반환 값은 다음과 같습니다.

  • Functions 2.x 이상에서 빈 본문이 있는 HTTP 204 No Content
  • Functions 1.x에서 빈 본문이 있는 HTTP 200 OK

HTTP 응답을 수정하려면 출력 바인딩을 구성합니다.

HTTP 바인딩에 대한 자세한 내용은 개요출력 바인딩 참조를 참조하세요.

HTTP 또는 WebHook를 사용할 계획인 경우 HttpClient의 부적절한 인스턴스화로 인해 발생할 수 있는 포트 소모를 피하도록 계획합니다. 자세한 내용은 Azure Functions에서 연결을 관리하는 방법을 참조하세요.

예제

C# 함수는 다음 C# 모드 중 하나를 사용하여 만들 수 있습니다.

이 문서의 코드는 Functions 버전 2.x 이상에서 사용되는 .NET Core 구문을 기본값으로 사용합니다. 1.x 구문에 대한 자세한 내용은 1.x 기능 템플릿을 참조하세요.

다음 예제는 쿼리 문자열이나 HTTP 요청의 본문에서 name 매개 변수를 찾는 C# 함수를 보여 줍니다. 반환 값은 출력 바인딩에 사용되지만, 반환 값 특성은 필요 없습니다.

[FunctionName("HttpTriggerCSharp")]
public static async Task<IActionResult> Run(
    [HttpTrigger(AuthorizationLevel.Function, "get", "post", Route = null)]
    HttpRequest req, ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    string name = req.Query["name"];

    string requestBody = String.Empty;
    using (StreamReader streamReader =  new  StreamReader(req.Body))
    {
        requestBody = await streamReader.ReadToEndAsync();
    }
    dynamic data = JsonConvert.DeserializeObject(requestBody);
    name = name ?? data?.name;

    return name != null
        ? (ActionResult)new OkObjectResult($"Hello, {name}")
        : new BadRequestObjectResult("Please pass a name on the query string or in the request body");
}

이 섹션에는 다음 예제가 포함되어 있습니다.

다음 예제에서는 HTTP 트리거 바인딩을 보여 줍니다.

쿼리 문자열에서 매개 변수 읽기

이 예제에서는 쿼리 문자열에서 id라는 매개 변수를 읽고 이 매개 변수를 사용하여 콘텐츠 형식 application/json으로 클라이언트에 반환되는 JSON 문서를 빌드합니다.

@FunctionName("TriggerStringGet")
public HttpResponseMessage run(
        @HttpTrigger(name = "req", 
            methods = {HttpMethod.GET}, 
            authLevel = AuthorizationLevel.ANONYMOUS)
        HttpRequestMessage<Optional<String>> request,
        final ExecutionContext context) {

    // Item list
    context.getLogger().info("GET parameters are: " + request.getQueryParameters());

    // Get named parameter
    String id = request.getQueryParameters().getOrDefault("id", "");

    // Convert and display
    if (id.isEmpty()) {
        return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
                        .body("Document not found.")
                        .build();
    } 
    else {
        // return JSON from to the client
        // Generate document
        final String name = "fake_name";
        final String jsonDocument = "{\"id\":\"" + id + "\", " + 
                                        "\"description\": \"" + name + "\"}";
        return request.createResponseBuilder(HttpStatus.OK)
                        .header("Content-Type", "application/json")
                        .body(jsonDocument)
                        .build();
    }
}

POST 요청에서 본문 읽기

이 예제에서는 POST 요청의 본문을 String으로 읽고, 이 매개 변수를 사용하여 콘텐츠 형식 application/json으로 클라이언트에 반환되는 JSON 문서를 빌드합니다.

    @FunctionName("TriggerStringPost")
    public HttpResponseMessage run(
            @HttpTrigger(name = "req", 
              methods = {HttpMethod.POST}, 
              authLevel = AuthorizationLevel.ANONYMOUS)
            HttpRequestMessage<Optional<String>> request,
            final ExecutionContext context) {

        // Item list
        context.getLogger().info("Request body is: " + request.getBody().orElse(""));

        // Check request body
        if (!request.getBody().isPresent()) {
            return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
                          .body("Document not found.")
                          .build();
        } 
        else {
            // return JSON from to the client
            // Generate document
            final String body = request.getBody().get();
            final String jsonDocument = "{\"id\":\"123456\", " + 
                                         "\"description\": \"" + body + "\"}";
            return request.createResponseBuilder(HttpStatus.OK)
                          .header("Content-Type", "application/json")
                          .body(jsonDocument)
                          .build();
        }
    }

경로에서 매개 변수 읽기

이 예제에서는 라우팅 경로에서 id라는 필수 매개 변수와 선택적 매개 변수 name을 읽은 후 이러한 매개 변수를 사용하여 콘텐츠 형식 application/json으로 클라이언트에 반환되는 JSON 문서를 빌드합니다. T

@FunctionName("TriggerStringRoute")
public HttpResponseMessage run(
        @HttpTrigger(name = "req", 
            methods = {HttpMethod.GET}, 
            authLevel = AuthorizationLevel.ANONYMOUS,
            route = "trigger/{id}/{name=EMPTY}") // name is optional and defaults to EMPTY
        HttpRequestMessage<Optional<String>> request,
        @BindingName("id") String id,
        @BindingName("name") String name,
        final ExecutionContext context) {

    // Item list
    context.getLogger().info("Route parameters are: " + id);

    // Convert and display
    if (id == null) {
        return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
                        .body("Document not found.")
                        .build();
    } 
    else {
        // return JSON from to the client
        // Generate document
        final String jsonDocument = "{\"id\":\"" + id + "\", " + 
                                        "\"description\": \"" + name + "\"}";
        return request.createResponseBuilder(HttpStatus.OK)
                        .header("Content-Type", "application/json")
                        .body(jsonDocument)
                        .build();
    }
}

POST 요청에서 POJO 본문 읽기

다음은 이 예제에서 참조되는 ToDoItem 클래스의 코드입니다.


public class ToDoItem {

  private String id;
  private String description;  

  public ToDoItem(String id, String description) {
    this.id = id;
    this.description = description;
  }

  public String getId() {
    return id;
  }

  public String getDescription() {
    return description;
  }

  @Override
  public String toString() {
    return "ToDoItem={id=" + id + ",description=" + description + "}";
  }
}

이 예제에서는 POST 요청의 본문을 읽습니다. 요청 본문은 자동으로 ToDoItem 개체로 역직렬화된 후 콘텐츠 형식 application/json을 사용하여 클라이언트에 반환됩니다. ToDoItem 매개 변수는 HttpMessageResponse.Builder 클래스의 body 속성에 할당될 때 Functions 런타임에 의해 직렬화됩니다.

@FunctionName("TriggerPojoPost")
public HttpResponseMessage run(
        @HttpTrigger(name = "req", 
            methods = {HttpMethod.POST}, 
            authLevel = AuthorizationLevel.ANONYMOUS)
        HttpRequestMessage<Optional<ToDoItem>> request,
        final ExecutionContext context) {

    // Item list
    context.getLogger().info("Request body is: " + request.getBody().orElse(null));

    // Check request body
    if (!request.getBody().isPresent()) {
        return request.createResponseBuilder(HttpStatus.BAD_REQUEST)
                        .body("Document not found.")
                        .build();
    } 
    else {
        // return JSON from to the client
        // Generate document
        final ToDoItem body = request.getBody().get();
        return request.createResponseBuilder(HttpStatus.OK)
                        .header("Content-Type", "application/json")
                        .body(body)
                        .build();
    }
}

다음 예제는 function.json 파일의 트리거 바인딩과 바인딩을 사용하는 JavaScript 함수를 보여줍니다. 함수는 쿼리 문자열이나 HTTP 요청의 본문에서 name 매개 변수를 찾습니다.

function.json 파일은 다음과 같습니다.

{
    "disabled": false,    
    "bindings": [
        {
            "authLevel": "function",
            "type": "httpTrigger",
            "direction": "in",
            "name": "req"
        },
        {
            "type": "http",
            "direction": "out",
            "name": "res"
        }
    ]
}

구성 섹션에서는 이러한 속성을 설명합니다.

JavaScript 코드는 다음과 같습니다.

module.exports = async function(context, req) {
    context.log('Node.js HTTP trigger function processed a request. RequestUri=%s', req.originalUrl);

    if (req.query.name || (req.body && req.body.name)) {
        context.res = {
            // status defaults to 200 */
            body: "Hello " + (req.query.name || req.body.name)
        };
    }
    else {
        context.res = {
            status: 400,
            body: "Please pass a name on the query string or in the request body"
        };
    }
};

다음 예제는 function.json의 트리거 바인딩 및 PowerShell 함수를 보여 줍니다. 함수는 쿼리 문자열이나 HTTP 요청의 본문에서 name 매개 변수를 찾습니다.

{
  "bindings": [
    {
      "authLevel": "function",
      "type": "httpTrigger",
      "direction": "in",
      "name": "Request",
      "methods": [
        "get",
        "post"
      ]
    },
    {
      "type": "http",
      "direction": "out",
      "name": "Response"
    }
  ]
}
using namespace System.Net

# Input bindings are passed in via param block.
param($Request, $TriggerMetadata)

# Write to the Azure Functions log stream.
Write-Host "PowerShell HTTP trigger function processed a request."

# Interact with query parameters or the body of the request.
$name = $Request.Query.Name
if (-not $name) {
    $name = $Request.Body.Name
}

$body = "This HTTP triggered function executed successfully. Pass a name in the query string or in the request body for a personalized response."

if ($name) {
    $body = "Hello, $name. This HTTP triggered function executed successfully."
}

# Associate values to output bindings by calling 'Push-OutputBinding'.
Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = [HttpStatusCode]::OK
    Body       = $body
})

다음 예제는 function.json 파일의 트리거 바인딩 및 바인딩을 사용하는 Python 함수를 보여줍니다. 함수는 쿼리 문자열이나 HTTP 요청의 본문에서 name 매개 변수를 찾습니다.

function.json 파일은 다음과 같습니다.

{
    "scriptFile": "__init__.py",
    "disabled": false,    
    "bindings": [
        {
            "authLevel": "function",
            "type": "httpTrigger",
            "direction": "in",
            "name": "req"
        },
        {
            "type": "http",
            "direction": "out",
            "name": "$return"
        }
    ]
}

구성 섹션에서는 이러한 속성을 설명합니다.

다음은 Python 코드입니다.

import logging
import azure.functions as func


def main(req: func.HttpRequest) -> func.HttpResponse:
    logging.info('Python HTTP trigger function processed a request.')

    name = req.params.get('name')
    if not name:
        try:
            req_body = req.get_json()
        except ValueError:
            pass
        else:
            name = req_body.get('name')

    if name:
        return func.HttpResponse(f"Hello {name}!")
    else:
        return func.HttpResponse(
            "Please pass a name on the query string or in the request body",
            status_code=400
        )

특성

In Process격리된 작업자 프로세스 C# 라이브러리는 모두 를 HttpTriggerAttribute 사용하여 트리거 바인딩을 정의합니다. C# 스크립트는 대신 function.json 구성 파일을 사용합니다.

In Process 함수에서 HttpTriggerAttribute는 다음 매개 변수를 지원합니다.

매개 변수 Description
AuthLevel 키가 있는 경우 함수를 호출하기 위해 요청에 포함되어야 하는 키를 결정합니다. 지원되는 값은 권한 부여 수준을 참조하세요.
메서드 함수에서 응답할 HTTP 메서드의 배열입니다. 이 속성을 지정하지 않으면 함수에서 모든 HTTP 메서드에 응답합니다. HTTP 엔드포인트 사용자 지정을 참조하세요.
Route 경로 템플릿을 정의하여 함수에서 응답할 요청 URL을 제어합니다. 값을 제공하지 않을 경우 기본값은 <functionname>입니다. 자세한 내용은 HTTP 엔드포인트 사용자 지정을 참조하세요.
WebHookType 버전 1.x 런타임에서만 지원됩니다.

HTTP 트리거가 지정된 공급자의 웹후크 수신기(receiver)로 작동하도록 구성합니다. 지원되는 값은 WebHook 형식을 참조하세요.

주석

Java 함수 런타임 라이브러리에서 다음 설정을 지원하는 HttpTrigger 주석을 사용합니다.

구성

다음 표에서는 런타임 버전에 따라 다른 function.json 파일에서 설정하는 트리거 구성 속성을 설명합니다.

다음 표에서는 function.json 파일에 설정된 바인딩 구성 속성을 설명합니다.

function.json 속성 Description
type 필수 - httpTrigger으로 설정해야 합니다.
direction 필수 - in으로 설정해야 합니다.
name 필수 - 요청 또는 요청 본문의 함수 코드에 사용되는 변수 이름입니다.
authLevel 키가 있는 경우 함수를 호출하기 위해 요청에 포함되어야 하는 키를 결정합니다. 지원되는 값은 권한 부여 수준을 참조하세요.
methods 함수에서 응답할 HTTP 메서드의 배열입니다. 이 속성을 지정하지 않으면 함수에서 모든 HTTP 메서드에 응답합니다. HTTP 엔드포인트 사용자 지정을 참조하세요.
route 경로 템플릿을 정의하여 함수에서 응답할 요청 URL을 제어합니다. 값을 제공하지 않을 경우 기본값은 <functionname>입니다. 자세한 내용은 HTTP 엔드포인트 사용자 지정을 참조하세요.

사용량

이 섹션에서는 HTTP 트리거 함수 바인딩을 구성하는 방법을 자세히 설명합니다.

HttpTrigger 주석은 다음 형식 중 하나의 메서드 매개 변수에 적용해야 합니다.

  • HttpRequestMessage<T>.
  • int, String, byte[]와 같은 모든 네이티브 Java 형식.
  • 선택적 값을 사용하는 null 허용 값.
  • POJO(Plain Old Java Object) 형식.

페이로드

트리거 입력 형식은 HttpRequest 또는 사용자 지정 형식으로 선언됩니다. HttpRequest를 선택하면 요청 개체에 대한 모든 권한을 갖게 됩니다. 사용자 지정 형식의 경우 런타임은 JSON 요청 본문의 구문을 분석하여 개체 속성을 설정하려고 합니다.

HTTP 엔드포인트 사용자 지정

기본적으로 HTTP 트리거용 함수를 만드는 경우 폼의 경로를 사용하여 이 함수의 주소를 지정할 수 있습니다.

http://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>

HTTP 트리거의 입력 바인딩에서 선택적 route 속성을 사용하여 이 경로를 사용자 지정할 수 있습니다. 매개 변수에서 웹 API 경로 제약 조건을 사용할 수 있습니다.

다음 C# 함수 코드는 경로에서 두 개의 매개 변수 categoryid를 허용하고 두 매개 변수를 모두 사용하여 응답을 작성합니다.

[FunctionName("Function1")]
public static IActionResult Run(
[HttpTrigger(AuthorizationLevel.Anonymous, "get", "post", Route = "products/{category:alpha}/{id:int?}")] HttpRequest req,
string category, int? id, ILogger log)
{
    log.LogInformation("C# HTTP trigger function processed a request.");

    var message = String.Format($"Category: {category}, ID: {id}");
    return (ActionResult)new OkObjectResult(message);
}

경로 매개 변수는 HttpTrigger 주석의 route 설정을 사용하여 정의합니다. 다음 함수 코드는 경로에서 두 개의 매개 변수 categoryid를 허용하고 두 매개 변수를 모두 사용하여 응답을 작성합니다.

package com.function;

import java.util.*;
import com.microsoft.azure.functions.annotation.*;
import com.microsoft.azure.functions.*;

public class HttpTriggerJava {
    public HttpResponseMessage<String> HttpTrigger(
            @HttpTrigger(name = "req",
                         methods = {"get"},
                         authLevel = AuthorizationLevel.FUNCTION,
                         route = "products/{category:alpha}/{id:int}") HttpRequestMessage<String> request,
            @BindingName("category") String category,
            @BindingName("id") int id,
            final ExecutionContext context) {

        String message = String.format("Category  %s, ID: %d", category, id);
        return request.createResponseBuilder(HttpStatus.OK).body(message).build();
    }
}

예를 들어, 다음 function.json 파일은 두 개의 매개 변수 categoryid를 사용하여 HTTP 트리거에 대한 route 속성을 정의합니다.

{
    "bindings": [
    {
        "type": "httpTrigger",
        "name": "req",
        "direction": "in",
        "methods": [ "get" ],
        "route": "products/{category:alpha}/{id:int?}"
    },
    {
        "type": "http",
        "name": "res",
        "direction": "out"
    }
    ]
}

Functions 런타임은 context 개체의 요청 본문을 제공합니다. 다음 예제에서는 context.bindingData에서 경로 매개 변수를 읽는 방법을 보여줍니다.

module.exports = async function (context, req) {

    var category = context.bindingData.category;
    var id = context.bindingData.id;
    var message = `Category: ${category}, ID: ${id}`;

    context.res = {
        body: message;
    }
}

function.json 파일에 선언된 경로 매개 변수는 $Request.Params 개체의 속성으로 액세스할 수 있습니다.

$Category = $Request.Params.category
$Id = $Request.Params.id

$Message = "Category:" + $Category + ", ID: " + $Id

Push-OutputBinding -Name Response -Value ([HttpResponseContext]@{
    StatusCode = [HttpStatusCode]::OK
    Body = $Message
})

함수 실행 컨텍스트는 func.HttpRequest로 선언된 매개 변수를 통해 노출됩니다. 이 인스턴스를 사용하면 함수에서 데이터 경로 매개 변수, 쿼리 문자열 값 및 HTTP 응답을 반환할 수 있는 메서드를 액세스할 수 있습니다.

정의되면 경로 매개 변수는 route_params 메서드를 호출하여 함수에 사용할 수 있습니다.

import logging

import azure.functions as func

def main(req: func.HttpRequest) -> func.HttpResponse:

    category = req.route_params.get('category')
    id = req.route_params.get('id')
    message = f"Category: {category}, ID: {id}"

    return func.HttpResponse(message)

이 구성을 사용하면 원래 경로 대신 다음 경로를 사용하여 함수의 주소를 지정할 수 있습니다.

http://<APP_NAME>.azurewebsites.net/api/products/electronics/357

이 구성으로 함수 코드에서 주소의 두 매개 변수, categoryid를 지원할 수 있습니다. URL에서 경로 매개 변수가 토큰화되는 방법에 대한 자세한 내용은 ASP.NET Core의 라우팅을 참조하세요.

기본적으로 모든 함수 경로에는 api 접두사가 붙습니다. host.json 파일에서 extensions.http.routePrefix 속성을 사용하여 접두사를 사용자 지정하거나 제거할 수도 있습니다. 다음 예제에서는 host.json 파일에서 빈 문자열을 접두사로 사용하여 api 경로 접두사를 제거합니다.

{
    "extensions": {
        "http": {
            "routePrefix": ""
        }
    }
}

경로 매개 변수 사용

함수의 route 패턴을 정의하는 경로 매개 변수는 각 바인딩에 사용할 수 있습니다. 예를 들어 "route": "products/{id}"로 정의된 경로가 있는 경우 테이블 스토리지 바인딩은 바인딩 구성에서 {id} 매개 변수의 값을 사용할 수 있습니다.

다음 구성에서는 {id} 매개 변수가 바인딩의 rowKey로 전달되는 방법을 보여 줍니다.

{
    "type": "table",
    "direction": "in",
    "name": "product",
    "partitionKey": "products",
    "tableName": "products",
    "rowKey": "{id}"
}

경로 매개 변수를 사용하는 경우 함수에 대해 invoke_URL_template이 자동으로 만들어집니다. 해당 URL 템플릿을 사용하여 클라이언트는 URL을 사용하여 함수를 호출할 때 URL에 전달해야 하는 매개 변수를 이해할 수 있습니다. Azure Portal에서 HTTP 트리거 함수 중 하나로 이동하고 함수 URL 가져오기를 선택합니다.

함수 나열 또는 함수 가져오기에 Azure Resource Manager API를 사용하여 프로그래밍 방식으로 invoke_URL_template에 액세스할 수 있습니다.

클라이언트 ID 사용

함수 앱이 App Service 인증 / 권한 부여를 사용하는 경우 코드에서 인증된 클라이언트에 대한 정보를 볼 수 있습니다. 이 정보는 플랫폼에 의해 삽입된 요청 헤더로서 사용할 수 있습니다.

데이터 바인딩에서 이 정보를 읽을 수도 있습니다. 이 기능은 2.x 이상의 Functions 런타임에서만 사용할 수 있습니다. 또한 이 기능은 현재 .NET 언어에 대해서만 사용할 수 있습니다.

인증된 클라이언트에 대한 정보는 다음 예제와 같이 요청 컨텍스트의 일부로 사용할 수 있는 ClaimsPrincipal로 사용할 수 있습니다.

using System.Net;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;

public static IActionResult Run(HttpRequest req, ILogger log)
{
    ClaimsPrincipal identities = req.HttpContext.User;
    // ...
    return new OkObjectResult();
}

또는 ClaimsPrincipal은 함수 시그니처에 단순히 추가 매개 변수로 포함될 수 있습니다.

using System.Net;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
using Newtonsoft.Json.Linq;

public static void Run(JObject input, ClaimsPrincipal principal, ILogger log)
{
    // ...
    return;
}

인증된 사용자는 HTTP 헤더를 통해 사용할 수 있습니다.

권한 부여 수준

권한 부여 수준은 함수 엔드포인트에 액세스하는 데 필요한 인증 키의 종류를 나타내는 문자열 값입니다. HTTP 트리거 함수의 경우 권한 부여 수준은 다음 값 중 하나일 수 있습니다.

수준 값 설명
익명 : API 키가 필요하지 않습니다.
function : 함수 전용 API 키가 필요합니다. 이는 수준이 특별히 설정되지 않은 경우 기본값입니다.
admin : 마스터 키가 필요합니다.

함수 액세스 키

함수에서는 키를 사용해 개발 중에 HTTP 함수 엔드포인트 액세스를 더 어렵게 만들 수 있습니다. HTTP 트리거 함수의 HTTP 액세스 수준이 anonymous로 설정되지 않는 경우 요청에는 API 액세스 키가 포함되어야 합니다.

키가 기본 보안 메커니즘을 제공하지만 프로덕션에서 HTTP 엔드포인트를 보호하기 위한 추가 옵션을 고려할 수 있습니다. 예를 들어 공용 앱에 공유 비밀을 배포하는 것은 일반적으로 좋지 않습니다. 공용 클라이언트에서 함수가 호출되는 경우 다른 보안 메커니즘 구현을 고려하는 것이 좋습니다. 자세히 알아보려면 프로덕션 환경에서 HTTP 엔드포인트 보호를 참조하세요.

함수 키 값을 갱신하는 경우 함수를 호출하는 모든 클라이언트에 업데이트된 키 값을 수동으로 다시 배포해야 합니다.

권한 부여 범위(함수 수준)

함수 수준 키에는 두 가지 액세스 범위가 있습니다.

  • 함수: 정의된 특정 함수에만 적용됩니다. API 키로 사용되면 이 키를 통해 해당 함수에만 액세스할 수 있습니다.

  • 호스트: 호스트 범위가 있는 키를 사용하여 함수 앱 내의 모든 함수에 액세스할 수 있습니다. API 키로 사용되면 이 키를 통해 함수 앱 내의 모든 함수에 액세스할 수 있습니다.

각 키의 이름은 참조될 수 있도록 지정되며 함수 및 호스트 수준에서는 "default"라는 기본 키가 있습니다. function 키는 호스트 키보다 우선합니다. 두 키가 동일한 이름으로 정의되면 항상 함수 키가 사용됩니다.

마스터 키(관리자 수준)

각 함수 앱에는 _master라는 관리자 수준 호스트 키도 있습니다. 마스터 키는 앱의 모든 함수에 대한 호스트 수준 액세스를 제공할 뿐만 아니라 런타임 REST API에 대한 관리 액세스도 제공합니다. 이 키를 취소할 수 없습니다. 액세스 수준을 admin으로 설정하면 요청에서 마스터 키를 사용해야 하며, 다른 키를 사용하면 액세스가 실패합니다.

주의

함수 앱에서는 마스터 키를 통해 높은 권한이 부여되므로, 이 키를 제3자와 공유하거나 네이티브 클라이언트 애플리케이션에 배포해서는 안 됩니다. 따라서 관리자 액세스 수준을 선택하는 경우 주의해야 합니다.

키 확보

키는 Azure에 함수 앱의 일부로 저장되며 나머지는 암호화되어 있습니다. 키를 보거나 새 키를 만들거나 키를 새 값으로 전환하려면 Azure Portal에서 HTTP 트리거 함수 중 하나로 이동한 다음 함수 키를 선택합니다.

호스트 키를 관리할 수도 있습니다. Azure Portal의 함수 앱으로 이동하고 앱 키를 선택합니다.

Azure Resource Manager API를 사용하여 프로그래밍 방식으로 함수 및 호스트 키를 가져올 수 있습니다. 함수 키 나열호스트 키 나열을 위한 API가 있으며, 배포 슬롯을 사용하는 경우 이에 해당하는 API는 함수 키 슬롯 나열호스트 키 슬롯 나열입니다.

함수 비밀 만들기 또는 업데이트, 함수 비밀 슬롯 만들기 또는 업데이트, 호스트 비밀 만들기 또는 업데이트호스트 비밀 슬롯 만들기 또는 업데이트 API를 사용하여 프로그래밍 방식으로 새 함수 및 호스트 키를 만들 수도 있습니다.

함수 및 호스트 키는 함수 비밀 삭제, 함수 비밀 슬롯 삭제, 호스트 비밀 삭제, 호스트 비밀 슬롯 삭제 API를 사용하여 프로그래밍 방식으로 삭제할 수 있습니다.

레거시 키 관리 API를 사용하여 함수 키를 가져올 수도 있지만 대신 Azure Resource Manager API를 사용하는 것이 좋습니다.

API 키 권한 부여

대다수 HTTP 트리거 템플릿을 사용할 때는 요청에 API 키가 필요합니다. 따라서 HTTP 요청은 일반적으로 다음 URL과 같습니다.

https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>?code=<API_KEY>

위에 나와 있는 것처럼 쿼리 문자열 변수 code에 키를 포함할 수 있습니다. x-functions-key HTTP 헤더에 키를 포함할 수도 있습니다. 키 값은 함수에 대해 정의된 모든 function 키 또는 모든 호스트 키일 수 있습니다.

키를 요구하지 않는 익명 요청을 허용할 수 있습니다. 마스터 키를 사용하도록 요구할 수도 있습니다. 바인딩 JSON에서 authLevel 속성을 사용하여 기본 권한 수준을 변경합니다. 자세한 내용은 트리거 - 구성을 참조하세요.

참고

함수를 로컬로 실행할 때는 지정된 권한 부여 수준 설정에 관계없이 권한 부여가 사용하지 않도록 설정됩니다. Azure에 게시하고 나면 트리거의 authLevel 설정이 적용됩니다. 컨테이너에서 로컬로 실행하는 경우에도 키가 필요합니다.

프로덕션 환경에서 HTTP 엔드포인트 보호

프로덕션 환경에서 함수 엔드포인트를 완벽하게 보호하려면 다음의 함수 앱 수준 보안 옵션 중 하나를 구현해야 합니다. 이러한 함수 앱 수준 보안 방법 중 하나를 사용할 때는 HTTP 트리거 함수 인증 수준을 anonymous로 설정해야 합니다.

App Service 인증/권한 부여를 사용하도록 설정

App Service 플랫폼에서는 AAD(Azure Active Directory) 및 기타 여러 타사 ID 공급자를 사용하여 클라이언트를 인증할 수 있습니다. 이 전략을 사용하여 함수용 사용자 지정 권한 부여 규칙을 구현할 수 있으며, 함수 코드에서 사용자 정보를 사용할 수 있습니다. 자세히 알아보려면 Azure App Service에서 인증 및 권한 부여클라이언트 ID 사용을 참조하세요.

Azure APIM(API Management)를 사용하여 요청 인증

APIM은 수신 요청에 사용할 수 있는 여러 가지 API 보안 옵션을 제공합니다. 자세히 알아보려면 API Management 인증 정책을 참조하세요. APIM을 적용하면 APIM 인스턴스의 IP 주소에서 보내는 요청만 수락하도록 함수 앱을 구성할 수 있습니다. 자세히 알아보려면 IP 주소 제한을 참조하세요.

격리로 함수 앱 배포

ASE(Azure App Service Environment)는 함수를 실행할 전용 호스팅 환경을 제공합니다. ASE 사용 시에는 모든 수신 요청을 인증하는 데 사용할 수 있는 단일 프런트 엔드 게이트웨이를 구성할 수 있습니다. 자세한 내용은 App Service Environment용 WAF(웹 애플리케이션 방화벽) 구성을 참조하세요.

Webhook

참고

웹후크 모드는 Functions 런타임의 버전 1.x에서만 사용 가능합니다. 버전 2.x 이상에서 HTTP 트리거의 성능 향상을 위해 이렇게 변경되었습니다.

버전 1.x에서 웹후크 템플릿은 웹후크 페이로드용으로 추가 유효성 검사를 제공합니다. 버전 2.x 이상의 경우 기본 HTTP 트리거가 계속 작동하며, 웹후크에는 이 방식을 사용하는 것이 좋습니다.

WebHook 형식

webHookType 바인딩 속성은 함수에서 지원하는 웹후크인 경우 형식을 나타내며, 지원되는 페이로드도 나타냅니다. 웹후크 형식은 다음 값 중 하나일 수 있습니다.

형식 값 Description
genericJson 특정 공급자를 위한 논리가 없는 범용 webhook 엔드포인트입니다. 이 설정은 HTTP POST 및 application/json 콘텐츠 형식을 사용하는 요청으로만 제한됩니다.
github 이 함수는 GitHub 웹후크에 응답합니다. GitHub 웹후크와 함께 authLevel 속성을 사용하지 마세요.
slack 이 함수는 Slack 웹후크에 응답합니다. Slack 웹후크와 함께 authLevel 속성을 사용하지 마세요.

webHookType 속성을 설정할 때 바인딩에 대한 methods 속성도 설정하지 마세요.

GitHub 웹후크

GitHub 웹후크에 응답하려면 먼저 HTTP 트리거를 사용하여 함수를 만들고 webHookType 속성을 github로 설정합니다. 그런 다음 URL 및 API 키를 GitHub 리포지토리의 웹후크 추가 페이지에 복사합니다.

함수에 웹후크를 추가하는 방법을 보여 주는 스크린샷

Slack 웹후크

Slack webhook은 함수 전용 키를 지정하는 대신 사용자를 위한 토큰을 생성하므로 Slack의 토큰을 사용하여 함수 전용 키를 구성해야 합니다. 권한 부여 키를 참조하세요.

웹후크 및 키

웹후크 인증은 HTTP 트리거의 일부로 웹후크 수신기 구성 요소에서 처리하며 메커니즘은 웹후크 유형에 따라 다릅니다. 각 메커니즘은 키를 사용합니다. 기본적으로 "default"라는 함수 키가 사용됩니다. 다른 키를 사용하려면 다음 중 한 가지 방법으로 요청과 함께 키 이름을 보내도록 웹후크 공급자를 구성합니다.

  • 쿼리 문자열: 공급자에서 clientid 쿼리 문자열 매개 변수에 키 이름을 전달합니다(예: https://<APP_NAME>.azurewebsites.net/api/<FUNCTION_NAME>?clientid=<KEY_NAME>).
  • 요청 헤더: 공급자에서 x-functions-clientid 헤더에 키 이름을 전달합니다.

내용 유형

C# 함수가 아닌 함수에 이진 및 폼 데이터를 전달하려면 적절한 content-type 헤더를 사용해야 합니다. 지원되는 콘텐츠 형식에는 이진 데이터의 경우 octet-stream다중 파트 형식이 포함됩니다.

알려진 문제

C# 함수가 아닌 함수에서 content-type image/jpeg을 사용하여 전송된 요청은 함수에 string 값을 전달합니다. 이와 같은 경우에는 string 값을 바이트 배열로 수동으로 변환하여 원시 이진 데이터에 액세스할 수 있습니다.

제한

HTTP 요청 길이는 100MB(104,857,600바이트)로 제한되고 URL 길이는 4KB(4,096바이트)로 제한됩니다. 이러한 제한은 런타임의 Web.config 파일httpRuntime 요소에 의해 지정됩니다.

HTTP 트리거를 사용하는 함수가 약 230초 안에 완료되지 않으면 Azure Load Balancer가 시간 제한을 적용하고 HTTP 502 오류를 반환합니다. 함수는 계속 실행되지만 HTTP 응답은 반환할 수 없습니다. 장기 실행 함수의 경우 비동기 패턴을 따르고 요청 상태를 ping할 수 있는 위치를 반환하는 것이 좋습니다. 함수 실행 시간에 대한 정보는 크기 조정 및 호스팅 - 소비 계획을 참조하세요.

다음 단계