使用 gcloud CLI 保護傳送至服務的流量

本頁面說明如何在 API Gateway 上部署 API,以便保護傳送至後端服務的流量。

請按照下列步驟,使用 Google Cloud CLI 部署新的 API,以便存取 Cloud Run 函式上的後端服務。本快速入門指南也說明如何使用 API 金鑰,保護後端免於遭到未經授權的存取。

事前準備

  1. 在 Google Cloud 控制台中,前往「Dashboard」頁面,選取或建立 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 命名規則,請參閱「API ID 規定」。
    • 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 Gateway 管理傳送至部署 API 後端的流量,您必須先設定 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 設定最多可能需要十分鐘才能完成。

  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 指令,在列出的 Managed Service 屬性中查看這項資訊。
    • 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 專案。

後續步驟