

Terjemahan disediakan oleh mesin penerjemah. Jika konten terjemahan yang diberikan bertentangan dengan versi bahasa Inggris aslinya, utamakan versi bahasa Inggris.

# Kontrol akses ke HTTP APIs dengan AWS Lambda otorisasi
<a name="http-api-lambda-authorizer"></a>

Anda menggunakan otorisasi Lambda untuk menggunakan fungsi Lambda untuk mengontrol akses ke HTTP API Anda. Kemudian, ketika klien memanggil API Anda, API Gateway memanggil fungsi Lambda Anda. API Gateway menggunakan respons dari fungsi Lambda Anda untuk menentukan apakah klien dapat mengakses API Anda.

## Versi format muatan
<a name="http-api-lambda-authorizer.payload-format"></a>

Versi format payload authorizer menentukan format data yang dikirimkan API Gateway ke pengotorisasi Lambda, dan bagaimana API Gateway menafsirkan respons dari Lambda. Jika Anda tidak menentukan versi format payload, akan Konsol Manajemen AWS menggunakan versi terbaru secara default. Jika Anda membuat otorisasi Lambda menggunakan AWS CLI,, atau SDK CloudFormation, Anda harus menentukan. `authorizerPayloadFormatVersion` Nilai yang di-support adalah `1.0` dan `2.0`. 

 Jika Anda membutuhkan kompatibilitas dengan REST APIs, gunakan versi`1.0`.

Contoh berikut menunjukkan struktur setiap versi format payload.

------
#### [ 2.0 ]

```
{
  "version": "2.0",
  "type": "REQUEST",
  "routeArn": "arn:aws:execute-api:us-east-1:123456789012:abcdef123/test/GET/request",
  "identitySource": ["user1", "123"],
  "routeKey": "$default",
  "rawPath": "/my/path",
  "rawQueryString": "parameter1=value1&parameter1=value2&parameter2=value",
  "cookies": ["cookie1", "cookie2"],
  "headers": {
    "header1": "value1",
    "header2": "value2"
  },
  "queryStringParameters": {
    "parameter1": "value1,value2",
    "parameter2": "value"
  },
  "requestContext": {
    "accountId": "123456789012",
    "apiId": "api-id",
    "authentication": {
      "clientCert": {
        "clientCertPem": "CERT_CONTENT",
        "subjectDN": "www.example.com",
        "issuerDN": "Example issuer",
        "serialNumber": "1",
        "validity": {
          "notBefore": "May 28 12:30:02 2019 GMT",
          "notAfter": "Aug  5 09:36:04 2021 GMT"
        }
      }
    },
    "domainName": "id.execute-api.us-east-1.amazonaws.com",
    "domainPrefix": "id",
    "http": {
      "method": "POST",
      "path": "/my/path",
      "protocol": "HTTP/1.1",
      "sourceIp": "IP",
      "userAgent": "agent"
    },
    "requestId": "id",
    "routeKey": "$default",
    "stage": "$default",
    "time": "12/Mar/2020:19:03:58 +0000",
    "timeEpoch": 1583348638390
  },
  "pathParameters": { "parameter1": "value1" },
  "stageVariables": { "stageVariable1": "value1", "stageVariable2": "value2" }
}
```

------
#### [ 1.0 ]

```
{
  "version": "1.0",
  "type": "REQUEST",
  "methodArn": "arn:aws:execute-api:us-east-1:123456789012:abcdef123/test/GET/request",
  "identitySource": "user1,123",
  "authorizationToken": "user1,123",
  "resource": "/request",
  "path": "/request",
  "httpMethod": "GET",
  "headers": {
    "X-AMZ-Date": "20170718T062915Z",
    "Accept": "*/*",
    "HeaderAuth1": "headerValue1",
    "CloudFront-Viewer-Country": "US",
    "CloudFront-Forwarded-Proto": "https",
    "CloudFront-Is-Tablet-Viewer": "false",
    "CloudFront-Is-Mobile-Viewer": "false",
    "User-Agent": "..."
  },
  "queryStringParameters": {
    "QueryString1": "queryValue1"
  },
  "pathParameters": {},
  "stageVariables": {
    "StageVar1": "stageValue1"
  },
  "requestContext": {
    "path": "/request",
    "accountId": "123456789012",
    "resourceId": "05c7jb",
    "stage": "test",
    "requestId": "...",
    "identity": {
      "apiKey": "...",
      "sourceIp": "...",
      "clientCert": {
        "clientCertPem": "CERT_CONTENT",
        "subjectDN": "www.example.com",
        "issuerDN": "Example issuer",
        "serialNumber": "a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1:a1",
        "validity": {
          "notBefore": "May 28 12:30:02 2019 GMT",
          "notAfter": "Aug  5 09:36:04 2021 GMT"
        }
      }
    },
    "resourcePath": "/request",
    "httpMethod": "GET",
    "apiId": "abcdef123"
  }
}
```

------

## Format respons otorisasi Lambda
<a name="http-api-lambda-authorizer.payload-format-response"></a>

Versi format payload juga menentukan struktur respons yang harus Anda kembalikan dari fungsi Lambda Anda.

### Respons fungsi Lambda untuk format 1.0
<a name="http-api-lambda-authorizer.v1"></a>

Jika Anda memilih versi `1.0` format, otorisasi Lambda harus menampilkan kebijakan IAM yang mengizinkan atau menolak akses ke rute API Anda. Anda dapat menggunakan sintaks kebijakan IAM standar dalam kebijakan. Untuk contoh kebijakan IAM, lihat[Kontrol akses untuk menjalankan API](api-gateway-control-access-using-iam-policies-to-invoke-api.md). Anda dapat meneruskan properti konteks ke integrasi Lambda atau mengakses log dengan menggunakan. `$context.authorizer.property` `context`Objek adalah opsional dan `claims` merupakan placeholder yang dicadangkan dan tidak dapat digunakan sebagai objek konteks. Untuk mempelajari selengkapnya, lihat [Sesuaikan log akses HTTP API](http-api-logging-variables.md).

**Example**    
****  

```
{
  "principalId": "abcdef", 
  "policyDocument": {
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Action": "execute-api:Invoke",
        "Effect": "Allow|Deny",
        "Resource": "arn:aws:execute-api:{regionId}:{accountId}:{apiId}/{stage}/{httpVerb}/[{resource}/[{child-resources}]]"
      }
    ]
  },
  "context": {
    "exampleKey": "exampleValue"
  }
}
```

### Respons fungsi Lambda untuk format 2.0
<a name="http-api-lambda-authorizer.v2"></a>

Jika Anda memilih versi `2.0` format, Anda dapat mengembalikan nilai Boolean atau kebijakan IAM yang menggunakan sintaks kebijakan IAM standar dari fungsi Lambda Anda. Untuk mengembalikan nilai Boolean, aktifkan tanggapan sederhana untuk otorisasi. Contoh berikut menunjukkan format yang harus Anda kodekan fungsi Lambda Anda untuk kembali. `context`Objek adalah opsional. Anda dapat meneruskan properti konteks ke integrasi Lambda atau mengakses log dengan menggunakan. `$context.authorizer.property` Untuk mempelajari selengkapnya, lihat [Sesuaikan log akses HTTP API](http-api-logging-variables.md).

------
#### [ Simple response ]

```
{
  "isAuthorized": true/false,
  "context": {
    "exampleKey": "exampleValue"
  }
}
```

------
#### [ IAM policy ]

****  

```
{
  "principalId": "abcdef", 
  "policyDocument": {
    "Version":"2012-10-17",		 	 	 
    "Statement": [
      {
        "Action": "execute-api:Invoke",
        "Effect": "Allow|Deny",
        "Resource": "arn:aws:execute-api:{regionId}:{accountId}:{apiId}/{stage}/{httpVerb}/[{resource}/[{child-resources}]]"
      }
    ]
  },
  "context": {
    "exampleKey": "exampleValue"
  }
}
```

------

## Contoh fungsi otorisasi Lambda
<a name="http-api-lambda-authorizer.example-code"></a>

Contoh berikut fungsi Lambda Node.js menunjukkan format respons yang diperlukan yang perlu Anda kembalikan dari fungsi Lambda Anda untuk versi format payload. `2.0`

------
#### [ Simple response - Node.js ]

```
export const handler = async(event) => {
    let response = {
        "isAuthorized": false,
        "context": {
            "stringKey": "value",
            "numberKey": 1,
            "booleanKey": true,
            "arrayKey": ["value1", "value2"],
            "mapKey": {"value1": "value2"}
        }
    };
    
    if (event.headers.authorization === "secretToken") {
        console.log("allowed");
        response = {
            "isAuthorized": true,
            "context": {
                "stringKey": "value",
                "numberKey": 1,
                "booleanKey": true,
                "arrayKey": ["value1", "value2"],
                "mapKey": {"value1": "value2"}
            }
        };
    }

    return response;

};
```

------
#### [ Simple response - Python ]

```
import json


def lambda_handler(event, context):
    response = {
        "isAuthorized": False,
        "context": {
            "stringKey": "value",
            "numberKey": 1,
            "booleanKey": True,
            "arrayKey": ["value1", "value2"],
            "mapKey": {"value1": "value2"}
        }
    }

    try:
        if (event["headers"]["authorization"] == "secretToken"):
            response = {
                "isAuthorized": True,
                "context": {
                    "stringKey": "value",
                    "numberKey": 1,
                    "booleanKey": True,
                    "arrayKey": ["value1", "value2"],
                    "mapKey": {"value1": "value2"}
                }
            }
            print('allowed')
            return response
        else:
            print('denied')
            return response
    except BaseException:
        print('denied')
        return response
```

------
#### [ IAM policy - Node.js ]

```
export const handler = async(event) => {
  if (event.headers.authorization == "secretToken") {
    console.log("allowed");
    return {
      "principalId": "abcdef", // The principal user identification associated with the token sent by the client.
      "policyDocument": {
        "Version": "2012-10-17",		 	 	 
        "Statement": [{
          "Action": "execute-api:Invoke",
          "Effect": "Allow",
          "Resource": event.routeArn
        }]
      },
      "context": {
        "stringKey": "value",
        "numberKey": 1,
        "booleanKey": true,
        "arrayKey": ["value1", "value2"],
        "mapKey": { "value1": "value2" }
      }
    };
  }
  else {
    console.log("denied");
    return {
      "principalId": "abcdef", // The principal user identification associated with the token sent by the client.
      "policyDocument": {
        "Version": "2012-10-17",		 	 	 
        "Statement": [{
          "Action": "execute-api:Invoke",
          "Effect": "Deny",
          "Resource": event.routeArn
        }]
      },
      "context": {
        "stringKey": "value",
        "numberKey": 1,
        "booleanKey": true,
        "arrayKey": ["value1", "value2"],
        "mapKey": { "value1": "value2" }
      }
    };
  }
};
```

------
#### [ IAM policy - Python ]

```
import json


def lambda_handler(event, context):
    response = {
        # The principal user identification associated with the token sent by
        # the client.
        "principalId": "abcdef",
        "policyDocument": {
            "Version": "2012-10-17",		 	 	 
            "Statement": [{
                "Action": "execute-api:Invoke",
                "Effect": "Deny",
                "Resource": event["routeArn"]
            }]
        },
        "context": {
            "stringKey": "value",
            "numberKey": 1,
            "booleanKey": True,
            "arrayKey": ["value1", "value2"],
            "mapKey": {"value1": "value2"}
        }
    }

    try:
        if (event["headers"]["authorization"] == "secretToken"):
            response = {
                # The principal user identification associated with the token
                # sent by the client.
                "principalId": "abcdef",
                "policyDocument": {
                    "Version": "2012-10-17",		 	 	 
                    "Statement": [{
                        "Action": "execute-api:Invoke",
                        "Effect": "Allow",
                        "Resource": event["routeArn"]
                    }]
                },
                "context": {
                    "stringKey": "value",
                    "numberKey": 1,
                    "booleanKey": True,
                    "arrayKey": ["value1", "value2"],
                    "mapKey": {"value1": "value2"}
                }
            }
            print('allowed')
            return response
        else:
            print('denied')
            return response
    except BaseException:
        print('denied')
        return response
```

------

## Sumber identitas
<a name="http-api-lambda-authorizer.identity-sources"></a>

Anda dapat secara opsional menentukan sumber identitas untuk otorisasi Lambda. Sumber identitas menentukan lokasi data yang diperlukan untuk mengotorisasi permintaan. Misalnya, Anda dapat menentukan nilai string header atau kueri sebagai sumber identitas. Jika Anda menentukan sumber identitas, klien harus memasukkannya dalam permintaan. Jika permintaan klien tidak menyertakan sumber identitas, API Gateway tidak memanggil otorisasi Lambda Anda, dan klien menerima kesalahan. `401`

Tabel berikut menjelaskan sumber identitas yang didukung untuk otorisasi Lambda.


| **Jenis** | **Contoh** | **Catatan** | 
| --- | --- | --- | 
| Nilai header | \$1 request.header. name | Nama header tidak peka huruf besar/kecil. | 
| Nilai string kueri | \$1request.querystring. name | Nama string kueri peka huruf besar/kecil. | 
| Variabel konteks | \$1 konteks. variableName | Nilai [variabel konteks](http-api-logging-variables.md) yang didukung. | 
| Variabel tahap | \$1 StageVariables. variableName | Nilai [variabel tahap](http-api-stages.stage-variables.md). | 

Anda juga dapat langsung kembali ` {"errorMessage" : "Unauthorized"}` dari fungsi Lambda Anda untuk mengembalikan `401` kesalahan ke klien Anda. Jika Anda langsung mengembalikan `401` kesalahan dari fungsi Lambda ke klien Anda, jangan tentukan sumber identitas apa pun saat Anda membuat otorisasi Lambda.

## Tanggapan otorisasi cache
<a name="http-api-lambda-authorizer.caching"></a>

Anda dapat mengaktifkan caching untuk otorisasi Lambda dengan menentukan file. [authorizerResultTtlInSeconds](https://docs.aws.amazon.com/apigatewayv2/latest/api-reference/apis-apiid-authorizers.html#apis-apiid-authorizers-prop-createauthorizerinput-authorizerresultttlinseconds) Saat caching diaktifkan untuk otorisasi, API Gateway menggunakan sumber identitas otorisasi sebagai kunci cache. Jika klien menentukan parameter yang sama dalam sumber identitas dalam TTL yang dikonfigurasi, API Gateway menggunakan hasil otorisasi yang di-cache, daripada menjalankan fungsi Lambda Anda.

Untuk mengaktifkan caching, otorisasi Anda harus memiliki setidaknya satu sumber identitas.

Jika Anda mengaktifkan respons sederhana untuk otorisasi, respons otorisasi sepenuhnya mengizinkan atau menolak semua permintaan API yang cocok dengan nilai sumber identitas cache. Untuk izin yang lebih terperinci, nonaktifkan tanggapan sederhana dan kembalikan kebijakan IAM. Bergantung pada otorisasi Anda, kebijakan IAM Anda mungkin perlu mengontrol akses ke beberapa.

Secara default, API Gateway menggunakan respons otorisasi yang di-cache untuk semua rute API yang menggunakan otorisasi. Untuk menyimpan respons per rute, tambahkan `$context.routeKey` ke sumber identitas otorisasi Anda.

## Buat Authorizer Lambda
<a name="http-api-lambda-authorizer.example-create"></a>

Saat membuat otorisasi Lambda, Anda menentukan fungsi Lambda untuk API Gateway yang akan digunakan. Anda harus memberikan izin API Gateway untuk menjalankan fungsi Lambda dengan menggunakan kebijakan sumber daya fungsi atau peran IAM. Perintah [create-authorizer berikut membuat authorizer](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/create-authorizer.html) Lambda:

```
aws apigatewayv2 create-authorizer \
    --api-id abcdef123 \
    --authorizer-type REQUEST \
    --identity-source '$request.header.Authorization' \
    --name lambda-authorizer \ 
    --authorizer-uri 'arn:aws:apigateway:us-west-2:lambda:path/2015-03-31/functions/arn:aws:lambda:us-west-2:123456789012:function:my-function/invocations' \
    --authorizer-payload-format-version '2.0' \
    --enable-simple-responses
```

Perintah [izin tambahan](https://docs.aws.amazon.com/cli/latest/reference/lambda/add-permission.html) berikut memperbarui kebijakan sumber daya fungsi Lambda untuk memberikan izin API Gateway untuk menjalankan fungsi tersebut. Jika API Gateway tidak memiliki izin untuk menjalankan fungsi Anda, klien akan menerima file. `500 Internal Server Error`

```
aws lambda add-permission \
    --function-name my-authorizer-function \
    --statement-id apigateway-invoke-permissions-abc123 \ 
    --action lambda:InvokeFunction \
    --principal apigateway.amazonaws.com \
    --source-arn "arn:aws:execute-api:us-west-2:123456789012:api-id/authorizers/authorizer-id"
```

Setelah Anda membuat otorisasi dan memberikan izin API Gateway untuk memanggilnya, perbarui rute Anda untuk menggunakan otorisasi. Perintah [update-route](https://docs.aws.amazon.com/cli/latest/reference/apigatewayv2/update-route.html) berikut menambahkan Lambda authorizer ke rute. Jika otorisasi Lambda Anda menggunakan caching kebijakan, pastikan Anda memperbarui kebijakan untuk mengontrol akses untuk rute tambahan.

```
aws apigatewayv2 update-route \
    --api-id abcdef123 \
    --route-id abc123 \
    --authorization-type CUSTOM \
    --authorizer-id def123
```

## Memecahkan masalah otorisasi Lambda
<a name="http-api-lambda-authorizer.troubleshooting"></a>

Jika API Gateway tidak dapat memanggil otorisasi Lambda Anda, atau otorisasi Lambda Anda mengembalikan respons dalam format yang tidak valid, klien akan menerima file. `500 Internal Server Error`

Untuk memecahkan masalah kesalahan, [aktifkan pencatatan akses untuk tahap](http-api-logging.md) API Anda. Sertakan variabel `$context.authorizer.error` logging dalam format log Anda.

Jika log menunjukkan bahwa API Gateway tidak memiliki izin untuk menjalankan fungsi Anda, perbarui kebijakan sumber daya fungsi Anda atau berikan peran IAM untuk memberikan izin API Gateway untuk memanggil otorisasi Anda.

[Jika log menunjukkan bahwa fungsi Lambda Anda mengembalikan respons yang tidak valid, verifikasi bahwa fungsi Lambda Anda mengembalikan respons dalam format yang diperlukan.](#http-api-lambda-authorizer.payload-format-response)