

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

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

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

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

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

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

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

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

有关使用 Amazon Location Service API 处理密钥的更多信息，请参阅《Amazon Location Service API 参考》**中的以下主题：
+ [CreateKey](https://docs.aws.amazon.com/location/latest/APIReference/API_geoapikeys_CreateKey.html)
+ [DeleteKey](https://docs.aws.amazon.com/location/latest/APIReference/API_geoapikeys_DeleteKey.html)
+ [DescribeKey](https://docs.aws.amazon.com/location/latest/APIReference/API_geoapikeys_DescribeKey.html)
+ [ListKeys](https://docs.aws.amazon.com/location/latest/APIReference/API_geoapikeys_ListKeys.html)
+ [UpdateKey](https://docs.aws.amazon.com/location/latest/APIReference/API_geoapikeys_UpdateKey.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.md)。
   + **客户端限制** –（可选）添加一个或多个 Web 域或者一个或多个 Android 或 Apple 应用程序，以便在其中使用 API 密钥。例如，如果 API 密钥是为了允许应用程序在网站 `example.com` 上运行，那么您可以将 `*.example.com/` 设置为允许的引用站点。
   + **标签** – （可选）向 API 密钥添加标签。

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

1. 在 API 密钥的详情页面上，您可以看到有关您创建的 API 密钥的信息。选择**显示 API 密钥**以查看您在调用 Amazon Location API 时使用的密钥值。键值的格式为 `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 Location API 中的 [CreateKey](https://docs.aws.amazon.com/location/latest/APIReference/API_geoapikeys_CreateKey.html) 操作。以下示例是一个 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_geoapikeys_DescribeKey.html) API 在以后查找密钥的密钥值。

------

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

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

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

支持 API 密钥的 API 还有一个采用 API 密钥值的附加参数。例如，如果您调用 `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()
    }
}
```

------