

本文属于机器翻译版本。若本译文内容与英语原文存在差异，则一律以英文原文为准。

# 使用 API 密钥进行身份验证
<a name="using-apikeys"></a>

**注意**  
API 密钥仅适用于**地图**、**地点**和**路线**资源，您无法修改或创建这些资源。如果您的应用程序需要访问其他资源或为未经身份验证的用户执行操作，则可以使用 Amazon Cognito 与 API 密钥一起提供访问权限或取代 API 密钥。有关更多信息，请参阅 [使用 Amazon Cognito 进行身份验证](authenticating-using-cognito.md)。

*API 密钥*是一个密钥值，它与您 AWS 账户中的特定 Amazon Location Service 资源或 API 以及您可以对这些资源执行的特定操作相关联。您可以在应用程序中使用 API 密钥对这些资源的亚马逊地址进行未经身份验证 APIs 的调用。

例如，如果您将 API 密钥与资源 API 相关联，则使用 and/or 该 `GetPlace*` API 密钥的应用程序将能够调用特定的 API 密钥 APIs。相同的 API 密钥不会授予更改或更新任何与其无关 APIs 的资源或调用的权限。

当您在应用程序 APIs 中调用 Amazon Location Service 时，您通常以有权进行 API 调用的*经过身份验证的用户*进行此调用。但是，在某些情况下，您不希望对应用程序的每个用户进行身份验证。

例如，您可能希望任何使用该网站的人都可以使用显示您的营业地点的 Web 应用程序，无论他们是否登录。在这种情况下，一种替代方法是使用 API 密钥进行 API 调用。

有关何时使用 API 密钥的更多信息，请参阅 [API 密钥最佳实践](#api-keys-best-practices)。

有关使用 Amazon Location Service API 处理密钥的更多信息，请参阅《Amazon Location Service API 参考》**中的以下主题：
+ [CreateKey](https://docs.aws.amazon.com/location/latest/APIReference/API_geotags_CreateKey.html)
+ [DeleteKey](https://docs.aws.amazon.com/location/latest/APIReference/API_geotags_DeleteKey.html)
+ [DescribeKey](https://docs.aws.amazon.com/location/latest/APIReference/API_geotags_DescribeKey.html)
+ [ListKeys](https://docs.aws.amazon.com/location/latest/APIReference/API_geotags_ListKeys.html)

## 为 Amazon Location Service 创建 API 密钥
<a name="create-api-key"></a>

您可以通过亚马逊定位服务控制台或亚马逊定位 API 创建 API 密钥。 AWS CLI请按照以下适当步骤继续操作。

------
#### [ Amazon Location console ]

**使用 Amazon Location Service 控制台创建 API 密钥**

1. 在[https://console.aws.amazon.com/location](https://console.aws.amazon.com/location)中，从左侧菜单中选择 **API 密钥**。

1. 在 **API 密钥**页面上，选择**创建 API 密钥**。

1. 在**创建 API 密钥**页面中，填写以下信息：
   + **名称**——您的 API 密钥的名称，例如 `ExampleKey`。
   + **描述** – API 密钥的可选描述。
   + **资源** – 在下拉列表中，选择要使用此 API 密钥访问的 Amazon Location 资源。您可以通过选择添加资源来**添加多个资源**。
   + **操作**——指定您要使用此 API 密钥授权的操作。必须至少选择一个操作才能匹配所选的每种资源类型。例如，如果您选择了地点资源，则必须在**地点操作**下选择至少一个选项。
   + **到期时间** – （可选）添加 API 密钥的到期日期和时间。有关更多信息，请参阅 [API 密钥最佳实践](#api-keys-best-practices)。
   + **客户端限制** –（可选）添加一个或多个 Web 域或者一个或多个 Android 或 Apple 应用程序，以便在其中使用 API 密钥。例如，如果 API 密钥是为了允许应用程序在网站 `example.com` 上运行，那么您可以将 `*.example.com/` 设置为允许的引用站点。
   + **标签** – （可选）向 API 密钥添加标签。

1. 选择**创建 API 密钥**以创建 API 密钥。

1. 在 API 密钥的详情页面上，您可以看到有关您创建的 API 密钥的信息。选择**显示 API 密钥**以查看您在调用 Amazon Location 时使用的密钥值 APIs。密钥值的格式为 `v1.public.a1b2c3d4...`。

------
#### [ AWS CLI ]

1. 使用 [create-key](https://docs.aws.amazon.com/cli/latest/reference/location/create-key.html) 命令。以下示例创建了一个名为 `ExampleKey` 的 API 密钥，该密钥没有到期日期，并且可以访问单个地图资源。

   ```
   aws location \
     create-key \
     --key-name ExampleKey \
     --restrictions '{"AllowActions":["geo-maps:*"],"AllowResources":["arn:aws:geo-maps:region::provider/default"]}' \
     --no-expiry
   ```

1. 响应中包含访问应用程序中的资源时要使用的 API 密钥值。键值的格式为 `v1.public.a1b2c3d4...`。要了解有关使用 API 密钥渲染地图的更多信息，请参阅 [使用 API 密钥调用 Amazon Location API](#using-apikeys-in-api)。对 create-key 的响应看起来与以下内容类似：

   ```
   {
       "Key": "v1.public.a1b2c3d4...",
       "KeyArn": "arn:aws:geo:region:accountId:api-key/ExampleKey",
       "KeyName": "ExampleKey",
       "CreateTime": "2023-02-06T22:33:15.693Z"
   }
   ```

1. 您也可以在以后使用 `describe-key` 来查找键值。以下示例演示了如何在名为 `ExampleKey` 的 API 密钥上调用 `describe-key`。

   ```
   aws location describe-key \
       --key-name ExampleKey
   ```

------
#### [ Amazon Location API ]

使用 Amazon 营业地点的[CreateKey](https://docs.aws.amazon.com/location/latest/APIReference/API_geotags_CreateKey.html)操作 APIs。以下示例是一个 API 请求，用于创建名为 `ExampleKey` 的 API 密钥，该密钥没有到期日期，并且可以访问单个地图资源。

```
POST /metadata/v0/keys HTTP/1.1
Content-type: application/json
{
  "KeyName": "ExampleKey",
  "NoExpiry": true,
  "Restrictions": {
    "AllowActions": [
      "geo-places:*",
      "geo-routes:*",
      "geo-maps:*"
    ],
    "AllowResources": [
      "arn:aws:geo-places:Region::provider/default",
      "arn:aws:geo-routes:Region::provider/default",
      "arn:aws:geo-maps:Region::provider/default"
    ]
  }
}
```

响应中包含访问应用程序中的资源时要使用的 API 密钥值。密钥值的格式为 `v1.public.a1b2c3d4...`。

您也可以使用 [DescribeKey](https://docs.aws.amazon.com/location/latest/APIReference/API_geotags_DescribeKey.html) API 在以后查找密钥的密钥值。

------

## 使用 API 密钥调用 Amazon Location API
<a name="using-apikeys-in-api"></a>

创建 API 密钥后，您可以使用该密钥值在应用程序 APIs 中调用 Amazon Location。

------
#### [ API ]

支持 API 密钥的还有一个采用 API 密钥值的附加参数。 APIs 例如，如果您调用 `GetPlace` API，则可以填写[密钥](https://docs.aws.amazon.com/location/latest/APIReference/API_geoplaces_GetPlace.html)参数，如下所示

```
curl --request GET —url 'https://places.geo.eu-central-1.amazonaws.com/v2/place/{PLACEID}?key={APIKEY}&language=jp'
```

------
#### [ AWS CLI ]

在使用 `--key` 参数时，还应使用 `--no-sign-request` 参数，以避免使用 Sig v4 进行签名。

```
aws geo-places get-place --place-id $PLACEID --language jp --key $APIKEY
```

------
#### [ SDK (web) ]

使用以下代码：

```
<!DOCTYPE html>
<html lang="en">
    <head>
        <title>Display a map</title>
        <meta property="og:description" content="Initialize a map in an HTML element with MapLibre GL JS." />
        <meta charset='utf-8'>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <link rel='stylesheet' href='https://unpkg.com/maplibre-gl@5.x/dist/maplibre-gl.css' />
        <script src='https://unpkg.com/maplibre-gl@5.x/dist/maplibre-gl.js'></script>
        <style>
            body { margin: 0; }
            #map { height: 100vh; }
        </style>
    </head>
    <body>
         
        <div id="map"></div>
        <script>
     
            const apiKey = "<api key>"; // check how to create api key for Amazon Location
            const mapStyle = "Standard";  // eg. Standard, Monochrome, Hybrid, Satellite  
            const awsRegion = "eu-central-1"; // eg. us-east-2, us-east-1, us-west-2, ap-south-1, ap-southeast-1, ap-southeast-2, ap-northeast-1, ca-central-1, eu-central-1, eu-west-1, eu-west-2, eu-south-2, eu-north-1, sa-east-1
            const styleUrl = `https://maps.geo.${awsRegion}.amazonaws.com/v2/styles/${mapStyle}/descriptor?key=${apiKey}`;


            const map = new maplibregl.Map({
                container: 'map', // container id
                style: styleUrl, // style URL
                center: [25.24,36.31], // starting position [lng, lat]
                zoom: 2, // starting zoom
            });
        </script>
    </body>
</html>
```

------
#### [ SDK (iOS, Swift) ]

使用以下代码：

```
import UIKit
import MapLibre

class ViewController: UIViewController {
    let apiKey = "Enter your API key" // The previously-created API Key to use
    let regionName = "Enter your region name" // The service region - us-east-1, ap-south-1, etc
    var mapView: MLNMapView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        loadMap()
    }
    
    func loadMap() {
        let styleName = "Standard" // The map style - Standard, Monochrome, Hybrid, Satellite
        let colorName = "Light" // The color scheme - Light, Dark
        
        // The Amazon Location Service map style URL that MapLibre will use to render the maps.
        let styleURL = URL(string: "https://maps.geo.\(regionName).amazonaws.com/v2/styles/\(styleName)/descriptor?key=\(apiKey)&color-scheme=\(colorName)")

        // Initialize MapLibre        
        mapView = MLNMapView(frame: view.bounds)
        mapView.styleURL = styleURL
        mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]
        // Set the starting camera position and zoom level for the map
        mapView.setCenter(CLLocationCoordinate2D(latitude: 49.246559, longitude: -123.063554), zoomLevel: 10, animated: false)
        view.addSubview(mapView!)
    }
}
```

------
#### [ SDK (Android, Kotlin) ]

使用以下代码：

```
class MapActivity : Activity(), OnMapReadyCallback {

    private lateinit var mBinding: ActivityMapBinding

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        initializeMap(savedInstanceState)
    }

    private fun initializeMap(savedInstanceState: Bundle?) {
        // Init MapLibre
        // See the MapLibre Getting Started Guide for more details
        // https://maplibre.org/maplibre-native/docs/book/android/getting-started-guide.html
        MapLibre.getInstance(this@MapActivity)
        mBinding = ActivityMapBinding.inflate(layoutInflater)
        setContentView(mBinding.root)
        mBinding.mapView.onCreate(savedInstanceState)
        mBinding.mapView.getMapAsync(this)
    }

    override fun onMapReady(mapLibreMap: MapLibreMap) {
        mapLibreMap.setStyle(Style.Builder().fromUri(getMapUrl())) {
            // Set the starting camera position
            mapLibreMap.cameraPosition = CameraPosition.Builder().target(LatLng(49.246559, -123.063554)).zoom(10.0).build()
            mapLibreMap.uiSettings.isLogoEnabled = false
            mapLibreMap.uiSettings.attributionGravity = Gravity.BOTTOM or Gravity.END
            mapLibreMap.uiSettings.setAttributionDialogManager(AttributionDialogManager(this, mapLibreMap))
        }
    }

    // Return the Amazon Location Service map style URL
    // MapLibre will use this to render the maps.
    // awsRegion: The service region - us-east-1, ap-south-1, etc
    // mapStyle: The map style - Standard, Monochrome, Hybrid, Satellite  
    // API_KEY: The previously-created API Key to use
    // colorName: The color scheme to use - Light, Dark
    private fun getMapUrl() =
           "https://maps.geo.${getString(R.string.awsRegion)}.amazonaws.com/v2/styles/${getString(R.string.mapStyle)}/descriptor?key=${BuildConfig.API_KEY}&color-scheme=${getString(R.string.colorName)}"

    override fun onStart() {
        super.onStart()
        mBinding.mapView.onStart()
    }

    override fun onResume() {
        super.onResume()
        mBinding.mapView.onResume()
    }

    override fun onPause() {
        super.onPause()
        mBinding.mapView.onPause()
    }

    override fun onStop() {
        super.onStop()
        mBinding.mapView.onStop()
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        mBinding.mapView.onSaveInstanceState(outState)
    }

    override fun onLowMemory() {
        super.onLowMemory()
        mBinding.mapView.onLowMemory()
    }

    override fun onDestroy() {
        super.onDestroy()
        mBinding.mapView.onDestroy()
    }
}
```

------

## 按请求源限制 API 密钥的使用
<a name="restrict-usage-by-origin"></a>

您可以为 API 密钥配置客户端限制，从而仅限访问特定的域或移动应用程序。按域进行限制时，只有当 HTTP 引用站点标头与您提供的值相匹配时，才会对请求进行授权。按 Android 或 Apple 应用程序进行限制时，只有当应用程序标识符 HTTP 标头字段与您提供的值相匹配时，才会对请求进行授权。

欲了解更多信息，请参阅[ApiKeyRestrictions](https://docs.aws.amazon.com/location/latest/APIReference/API_geotags_ApiKeyRestrictions.html)《*亚马逊定位服务 API 参考*》。

**Android 应用程序标识符：**
+ `X-Android-Package`:

  Android 应用程序的唯一标识符，在应用程序的 `build.gradle` 文件中定义，通常采用反向域格式。

  示例：

  `com.mydomain.appname`
+ `X-Android-Cert`:

  用于签署 Android APK 的签名证书的 SHA-1 哈希值。

  示例：

  `BB:0D:AC:74:D3:21:E1:43:67:71:9B:62:91:AF:A1:66:6E:44:5D:75`

**Apple 应用程序标识符：**
+ `X-Apple-Bundle-Id `:

  Apple（iOS、macOS 等）应用程序的唯一标识符，在应用程序的 `Info.plist` 中定义，通常采用反向域格式。

  示例：

  `com.mydomain.appname`

## API 密钥最佳实践
<a name="api-keys-best-practices"></a>

API 密钥包含一个纯文本*值，该值*允许访问一个或多个资源或 APIs 您的资源 AWS 账户。如果有人复制了您的 API 密钥，他们就可以访问相同的资源和 APIs。为尽可能地减少潜在影响，请查看以下最佳实践：
+ **限制 API 密钥**

  为避免出现上述情况，最好限制您的 API 密钥。创建密钥时，您可以指定能够使用该密钥的域、Android 应用程序或 Apple 应用程序。
+ **管理 API 密钥的生命周期**

  您可以创建无限期有效的 API 密钥。但是，如果您想创建临时 API 密钥、定期轮换 API 密钥或撤销现有 API 密钥，则可以使用 *API 密钥过期时间*。
  + 您可以在创建或更新 API 密钥时为其设置过期时间。
  + API 密钥在到达其到期时间时将会自动停用。非活动密钥不能再用于发出请求。
  + 您可以通过删除过期时间，将临时密钥更改为永久密钥。
  + 您可以在 API 密钥停用 90 天后将其删除。
  + 如果您尝试停用过去七天内使用过的 API 密钥，系统会提示您确认是否要进行更改。

    如果您使用的是 Amazon Location Service API 或`true`，请将`ForceUpdate`参数设置为，否则您将收到错误消息。 AWS CLI