使用 gcloud CLI 保护到服务的流量

本页面介绍如何在 API Gateway 上部署 API 以保护流向后端服务的流量。

请按照以下步骤使用 Google Cloud CLI 部署新的 API 以访问 Cloud Run 函数上的后端服务。本快速入门还介绍了如何使用 API 密钥保护您的后端免遭未经授权的访问。

准备工作

  1. 在 Google Cloud 控制台中,转到信息中心页面,然后选择或创建 Google Cloud 项目。

    转到信息中心

  2. 确认您的项目已启用结算功能。

    启用结算功能

  3. 确保您的机器下载并安装了 Google Cloud CLI。

    下载 gcloud CLI

  4. 更新 gcloud 组件:

    gcloud components update
  5. 设置默认项目。将 PROJECT_ID 替换为您的 Google Cloud 项目 ID。

    gcloud config set project PROJECT_ID

启用必需服务

API Gateway 要求您启用以下 Google 服务:

名称 标题
apigateway.googleapis.com API Gateway API
servicemanagement.googleapis.com Service Management API
servicecontrol.googleapis.com Service Control API

如需确认已启用必需的服务,请运行以下命令:

gcloud services list

如果您没有看到列出的必需服务,请启用它们:

gcloud services enable apigateway.googleapis.com
gcloud services enable servicemanagement.googleapis.com
gcloud services enable servicecontrol.googleapis.com

如需详细了解 gcloud 服务,请参阅 gcloud 服务

部署 API 后端

API Gateway 位于已部署的后端服务前面,并处理所有传入请求。在本快速入门中,API Gateway 将传入的调用路由到名为 helloGET 的 Cloud Run 函数后端,该后端包含以下函数:

/**
 * HTTP Cloud Function.
 * This function is exported by index.js, and is executed when
 * you make an HTTP request to the deployed function's endpoint.
 *
 * @param {Object} req Cloud Function request context.
 *                     More info: https://expressjs.com/en/api.html#req
 * @param {Object} res Cloud Function response context.
 *                     More info: https://expressjs.com/en/api.html#res
 */

exports.helloGET = (req, res) => {
  res.send('Hello World!');
};

按照快速入门:使用 Google Cloud CLI 中的步骤下载示例 Cloud Run 函数代码并部署 Cloud Run 函数后端服务。

创建 API

现在,您可以在 API Gateway 上创建 API 了。

  1. 输入以下命令,其中:

    • API_ID 指定 API 的名称。 请参阅 API ID 要求,了解 API 命名准则。
    • PROJECT_ID 指定您的 Google Cloud 项目的名称。
    gcloud api-gateway apis create API_ID --project=PROJECT_ID

    例如:

    gcloud api-gateway apis create my-api --project=my-project
  2. 成功完成后,您可以使用以下命令查看有关新 API 的详细信息:

    gcloud api-gateway apis describe API_ID --project=PROJECT_ID

    例如:

    gcloud api-gateway apis describe my-api --project=my-project

    此命令会返回以下内容:

      createTime: '2020-02-29T21:52:20.297426875Z'
      displayName: my-api
      managedService: my-api-123abc456def1.apigateway.my-project.cloud.goog
      name: projects/my-project/locations/global/apis/my-api
      state: ACTIVE
      updateTime: '2020-02-29T21:52:20.647923711Z'

请记下 managedService 属性的值。 此值用于在后续步骤中启用您的 API。

创建 API 配置

您需要 API 配置,才能使用 API Gateway 来管理发送到已部署的 API 后端的流量。

您可以使用包含专用注释的 OpenAPI 规范来创建 API 配置,以定义所选的 API Gateway 行为。本快速入门中使用的 OpenAPI 规范包含在我们的 Cloud Run 函数后端的路由说明:

# openapi2-functions.yaml
swagger: '2.0'
info:
  title: API_ID optional-string
  description: Sample API on API Gateway with a Google Cloud Functions backend
  version: 1.0.0
schemes:
  - https
produces:
  - application/json
paths:
  /hello:
    get:
      summary: Greet a user
      operationId: hello
      x-google-backend:
        address: https://GCP_REGION-PROJECT_ID.cloudfunctions.net/helloGET
      responses:
        '200':
          description: A successful response
          schema:
            type: string

如需上传此 OpenAPI 规范并使用 gcloud CLI 创建 API 配置,请执行以下操作:

  1. 通过命令行创建名为 openapi2-functions.yaml 的新文件。

  2. 复制上面显示的 OpenAPI 规范的内容并粘贴到新创建的文件中。

  3. 按如下方式修改该文件:

    1. title 字段中,将 API_ID 替换为您的 API 名称,并将 optional-string 替换为您选择的简要说明。在创建授予对此 API 访问权限的 API 密钥时,会用到此字段的值。
    2. address 字段中,将 GCP_REGION 替换为已部署函数的 Google Cloud 区域,并将 PROJECT_ID 替换为您的 Google Cloud 项目的名称。
  4. 输入以下命令,其中:

    • CONFIG_ID 指定 API 配置的名称。
    • API_ID 指定 API 的名称。
    • API_DEFINITION 指定 OpenAPI 规范的文件名。
    • PROJECT_ID 指定您的 Google Cloud 项目的名称。
    • SERVICE_ACCOUNT_EMAIL 用于指定用于为已配置身份验证的后端签名令牌的服务账号。如需了解详情,请参阅配置服务账号
    gcloud api-gateway api-configs create CONFIG_ID \
      --api=API_ID --openapi-spec=API_DEFINITION \
      --project=PROJECT_ID --backend-auth-service-account=SERVICE_ACCOUNT_EMAIL

    例如:

    gcloud api-gateway api-configs create my-config \
      --api=my-api --openapi-spec=openapi2-functions.yaml \
      --project=my-project --backend-auth-service-account=0000000000000-compute@developer.gserviceaccount.com

    此操作可能需要几分钟才能完成,因为 API 配置会传播到下游系统。复杂 API 配置的创建最多可能需要 10 分钟才能完成。

  5. 创建 API 配置后,您可以运行以下命令来查看其详细信息:

    gcloud api-gateway api-configs describe CONFIG_ID \
      --api=API_ID --project=PROJECT_ID

    例如:

    gcloud api-gateway api-configs describe my-config \
      --api=my-api --project=my-project

    输出会显示 API 配置详细信息,包括名称和状态,如以下示例所示:

    createTime: '2020-02-07T18:17:01.839180746Z'
    displayName: my-config
    gatewayConfig:
    backendConfig:
      googleServiceAccount: 0000000000000-compute@developer.gserviceaccount.com
    name: projects/my-project/locations/global/apis/my-api/configs/my-config
    serviceRollout:
    rolloutId: 2020-02-07r0
    state: ACTIVE
    updateTime: '2020-02-07T18:17:02.173778118Z'

创建网关

接下来,在网关上部署 API 配置。在网关上部署 API 配置定义了 API 客户端可用于访问 API 的外部网址。

运行以下命令,将刚创建的 API 配置部署到 API Gateway:

gcloud api-gateway gateways create GATEWAY_ID \
  --api=API_ID --api-config=CONFIG_ID \
  --location=GCP_REGION --project=PROJECT_ID

其中:

  • GATEWAY_ID 指定网关的名称。
  • API_ID 指定与此网关关联的 API Gateway API 的名称。
  • CONFIG_ID 指定部署到网关的 API 配置的名称。
  • GCP_REGION 是已部署网关的 Google Cloud 区域

  • PROJECT_ID 指定您的 Google Cloud 项目的名称。

例如:

gcloud api-gateway gateways create my-gateway \
  --api=my-api --api-config=my-config \
  --location=us-central1 --project=my-project

成功完成后,请使用以下命令查看有关网关的详细信息:

gcloud api-gateway gateways describe GATEWAY_ID \
  --location=GCP_REGION --project=PROJECT_ID

例如:

gcloud api-gateway gateways describe my-gateway \
  --location=us-central1 --project=my-project

此命令会返回以下内容:

apiConfig: projects/my-project/locations/global/apis/my-api/configs/my-config
createTime: '2020-02-05T13:44:12.997862831Z'
defaultHostname: my-gateway-a12bcd345e67f89g0h.uc.gateway.dev
displayName: my-gateway
name: projects/my-project/locations/us-central1/gateways/my-gateway
serviceAccount:
      email: 0000000000000-compute@developer.gserviceaccount.com
state: ACTIVE
updateTime: '2020-02-05T13:45:00.844705087Z'

请记下 defaultHostname 属性的值。 这是您在下一步中用于测试部署的网关网址的主机名部分。

测试您的 API 部署

现在,您可以使用部署网关时生成的网址向 API 发送请求。

输入以下 curl 命令,其中:

  • DEFAULT_HOSTNAME 指定已部署的网关网址的主机名部分。
  • hello 是 API 配置中指定的路径。
curl https://DEFAULT_HOSTNAME/hello

例如:

curl https://my-gateway-a12bcd345e67f89g0h.uc.gateway.dev/hello

输出如下:

Hello World!

您已成功创建和部署 API Gateway!

使用 API 密钥保护访问

要保护对 API 后端的访问,请生成与项目关联的 API 密钥,并授予该密钥调用您的 API 的权限。如需了解详情,请参阅使用 API 密钥限制 API 访问权限

如果您没有与本快速入门中使用的 Google Cloud 项目关联的 API 密钥,则可以按照创建 API 密钥中的步骤添加一个。

如需使用 API 密钥保护对网关的访问,请执行以下操作:

  1. 为您的服务启用 API 密钥支持。 输入以下命令,其中:
    • MANAGED_SERVICE_NAME 指定您在部署 API 时创建的代管式服务的名称。这可以通过 gcloud apigee-gateway apis describe 命令列出的代管式服务属性查看。
    • PROJECT_ID 指定您的 Google Cloud 项目的名称。
    gcloud services enable MANAGED_SERVICE_NAME.apigateway.PROJECT_ID.cloud.goog
    例如:
    gcloud services enable my-api-123abc456def1.apigateway.my-project.cloud.goog
  2. 修改用于创建 API 配置的 OpenAPI 规范,以包括对所有流量强制执行 API 密钥验证安全政策的说明。 添加 security 类型和 securityDefinitions,如下所示:
      # openapi2-functions.yaml
      swagger: '2.0'
      info:
        title: API_ID optional-string
        description: Sample API on API Gateway with a Google Cloud Functions backend
        version: 1.0.0
      schemes:
        - https
      produces:
        - application/json
      paths:
        /hello:
          get:
            summary: Greet a user
            operationId: hello
            x-google-backend:
              address: https://GCP_REGION-PROJECT_ID.cloudfunctions.net/helloGET
            security:
            - api_key: []
            responses:
              '200':
                description: A successful response
                schema:
                  type: string
      securityDefinitions:
        # This section configures basic authentication with an API key.
        api_key:
          type: "apiKey"
          name: "key"
          in: "query"
    securityDefinition 将 API 配置为要求请求访问规范中定义的所有路径时作为名为 key 的查询参数传递的 API 密钥。
  3. 使用以下命令使用修改后的 OpenAPI 规范创建新的 API 配置:
    gcloud api-gateway api-configs create NEW_CONFIG_ID \
    --api=API_ID --openapi-spec=NEW_API_DEFINITION \
    --project=PROJECT_ID --backend-auth-service-account=SERVICE_ACCOUNT_EMAIL
    例如:
    gcloud api-gateway api-configs create my-config-key \
      --api=my-api --openapi-spec=openapi2-functions.yaml \
      --project=my-project --backend-auth-service-account=0000000000000compute@developer.gserviceaccount.com
  4. 运行以下命令,使用新的 API 配置更新现有网关
    gcloud api-gateway gateways update GATEWAY_ID \
      --api=API_ID --api-config=NEW_CONFIG_ID \
      --location=GCP_REGION --project=PROJECT_ID
    例如:
    gcloud api-gateway gateways update my-gateway \
      --api=my-api --api-config=my-config-key \
      --location=us-central1 --project=my-project

测试您的 API 密钥

创建和部署修改后的 API 后,尝试向其发出请求。

输入以下 curl 命令,其中:

  • DEFAULT_HOSTNAME 指定已部署的网关网址的主机名部分。
  • hello 是 API 配置中指定的路径。
curl https://DEFAULT_HOSTNAME/hello

例如:

curl https://my-gateway-a12bcd345e67f89g0h.uc.gateway.dev/hello

这会导致以下错误:

UNAUTHENTICATED:Method doesn't allow unregistered callers (callers without established identity). Please use API Key or other form of API consumer identity to call this API.

现在,输入以下 curl 命令,其中:

  • DEFAULT_HOSTNAME 指定已部署的网关网址的主机名部分。
  • hello 是 API 配置中指定的路径。
  • API_KEY 指定您在上一步中创建的 API 密钥。
curl https://DEFAULT_HOSTNAME/hello?key=API_KEY

现在,您应该会在 API 的响应中看到 Hello World!

恭喜!您已成功使用 API Gateway 保护 API 后端。现在,您可以通过生成其他 API 密钥来开始初始配置新的 API 客户端。

清理

为避免系统因本快速入门中使用的资源向您的 Google Cloud 账号收取费用,您可以执行以下操作:

或者,您还可以删除本教程中使用的 Google Cloud 项目。

后续步骤