Início rápido: proteja o tráfego para um serviço com a CLI gcloud

Esta página mostra como implementar uma API no API Gateway para proteger o tráfego para um serviço de back-end.

Siga estes passos para implementar uma nova API para aceder a um serviço de back-end nas funções do Cloud Run através da Google Cloud CLI. Este início rápido também descreve como usar uma chave da API para proteger o seu back-end contra acesso não autorizado.

Antes de começar

  1. Na Google Cloud consola, aceda à página Painel de controlo e selecione ou crie um Google Cloud projeto.

    Aceder ao painel de controlo

  2. Confirme se a faturação está ativada para o seu projeto.

    Ative a faturação

  3. Verifique se a CLI Google Cloud foi transferida e instalada no seu computador.

    Transfira a CLI gcloud

  4. Atualize os componentes de gcloud:

    gcloud components update
  5. Defina o projeto predefinido. Substitua PROJECT_ID pelo ID do seu Google Cloud projeto.

    gcloud config set project PROJECT_ID

Ative os serviços necessários

O API Gateway requer que ative os seguintes serviços Google:

Nome Título
apigateway.googleapis.com API do API Gateway
servicemanagement.googleapis.com Service Management API
servicecontrol.googleapis.com Service Control API

Use os seguintes comandos para ativar estes serviços:

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

Para mais informações sobre os serviços gcloud, consulte os serviços gcloud.

Implemente um back-end de API

O API Gateway está posicionado à frente de um serviço de back-end implementado e processa todos os pedidos recebidos. Neste início rápido, o API Gateway encaminha as chamadas recebidas para um back-end de função do Cloud Run denominado helloGET que contém a seguinte função:

/**
 * 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!');
};

Siga os passos no Início rápido: usar a CLI Google Cloud para transferir o código de exemplo das funções do Cloud Run e implementar o serviço de back-end da função do Cloud Run.

Crie uma API

Agora, está tudo pronto para criar a sua API no API Gateway.

  1. Introduza o seguinte comando, em que:

    • API_ID especifica o nome da sua API. Consulte os requisitos de ID da API para ver as diretrizes de nomenclatura da API.
      gcloud api-gateway apis create API_ID 

    Por exemplo:

    gcloud api-gateway apis create my-api
  2. Após a conclusão com êxito, pode usar o seguinte comando para ver detalhes sobre a nova API:

    gcloud api-gateway apis describe API_ID 

    Por exemplo:

    gcloud api-gateway apis describe my-api 

    Este comando devolve o seguinte:

      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'

Tome nota do valor da propriedade managedService. Este valor é usado para ativar a sua API num passo subsequente.

Crie uma configuração de API

Antes de poder usar o API Gateway para gerir o tráfego para o back-end da API implementado, precisa de uma configuração da API.

Pode criar uma configuração da API através de uma descrição OpenAPI que contenha anotações especializadas para definir o comportamento escolhido do API Gateway. Para mais detalhes sobre as extensões OpenAPI suportadas, consulte o seguinte:

A descrição da OpenAPI usada para este início rápido contém instruções de encaminhamento para o nosso back-end de funções do Cloud Run:

OpenAPI 2.0

# openapi-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://GATEWAY_LOCATION-PROJECT_ID.cloudfunctions.net/helloGET
      responses:
        '200':
          description: A successful response
          schema:
            type: string

OpenAPI 3.x

# openapi-functions.yaml
openapi: 3.0.4
info:
  title: API_ID optional-string
  description: Sample API on API Gateway with a Google Cloud Functions backend
  version: 1.0.0
# Define reusable components in x-google-api-management
x-google-api-management:
  backend:
    functions_backend:
      address: https://GATEWAY_LOCATION-PROJECT_ID.cloudfunctions.net/helloGET
      pathTranslation: APPEND_PATH_TO_ADDRESS
      protocol: "http/1.1"
# Apply the backend configuration by referencing it by name. Set at the root so this applies to all operations unless overridden.
x-google-backend: functions_backend
paths:
  /hello:
    get:
      summary: Greet a user
      operationId: hello
      responses:
        '200':
          description: A successful response
          content:
            application/json:
              schema:
                type: string

Para carregar esta descrição da OpenAPI e criar uma configuração da API através da CLI gcloud:

  1. Na linha de comandos, crie um novo ficheiro com o nome openapi-functions.yaml.

  2. Copie e cole o conteúdo da descrição da OpenAPI no ficheiro recém-criado.

  3. Edite o ficheiro da seguinte forma:

    1. No campo title, substitua API_ID pelo nome da sua API e substitua optional-string por uma breve descrição à sua escolha. O valor deste campo é usado quando são geradas chaves de API que concedem acesso a esta API.
    2. No campo address, substitua GATEWAY_LOCATION pela Google Cloud região da função implementada e PROJECT_ID pelo nome do seu Google Cloud projeto.
  4. Introduza o seguinte comando, em que:

    • CONFIG_ID especifica o nome da configuração da API.
    • API_ID especifica o nome da sua API.
    • API_DEFINITION especifica o nome do ficheiro da especificação OpenAPI.
    • SERVICE_ACCOUNT_EMAIL especifica a conta de serviço usada para assinar tokens para back-ends com autenticação configurada. Para mais informações, consulte o artigo Configurar uma conta de serviço.
    gcloud api-gateway api-configs create CONFIG_ID \
      --api=API_ID --openapi-spec=API_DEFINITION \
       --backend-auth-service-account=SERVICE_ACCOUNT_EMAIL

    Por exemplo:

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

    Esta operação pode demorar vários minutos a ser concluída, uma vez que a configuração da API é propagada para sistemas a jusante. A criação de uma configuração de API complexa pode demorar até dez minutos a ser concluída com êxito.

  5. Depois de criar a configuração da API, pode ver os respetivos detalhes executando este comando:

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

    Por exemplo:

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

    O resultado mostra os detalhes da configuração da API, incluindo o nome e o estado, conforme mostrado no exemplo seguinte:

    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'

Criar um gateway

Agora, implemente a configuração da API num gateway. A implementação de uma configuração da API num gateway define um URL externo que os clientes da API podem usar para aceder à sua API.

Execute o seguinte comando para implementar a configuração da API que acabou de criar no API Gateway:

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

where:

  • GATEWAY_ID especifica o nome da gateway.
  • API_ID especifica o nome da API do gateway da API associada a este gateway.
  • CONFIG_ID especifica o nome da configuração da API implementada no gateway.
  • GCP_REGION é a Google Cloud região para o gateway implementado.

  • PROJECT_ID especifica o nome do seu Google Cloud projeto.

Por exemplo:

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

Após a conclusão com êxito, use o seguinte comando para ver detalhes sobre o gateway:

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

Por exemplo:

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

Este comando devolve o seguinte:

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'

Tome nota do valor da propriedade defaultHostname. Esta é a parte do nome do anfitrião do URL do gateway que usa para testar a implementação no passo seguinte.

Teste a implementação da API

Agora, pode enviar pedidos para a sua API através do URL gerado após a implementação da gateway.

Introduza o seguinte comando curl, em que:

  • DEFAULT_HOSTNAME especifica a parte do nome do anfitrião do URL da gateway implementada.
  • hello é o caminho especificado na configuração da API.
curl https://DEFAULT_HOSTNAME/hello

Por exemplo:

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

O resultado é:

Hello World!

Criou e implementou um gateway de API com êxito!

Acesso seguro através de uma chave da API

Para proteger o acesso ao seu back-end da API, gere uma chave da API associada ao seu projeto e conceda a essa chave acesso para chamar a sua API. Consulte o artigo Restringir o acesso à API com chaves da API para mais informações.

Se ainda não tiver uma chave da API associada ao Google Cloud projeto que está a usar neste guia de início rápido, pode adicionar uma seguindo os passos em Criar uma chave da API.

Para proteger o acesso ao seu gateway através de uma chave da API:

  1. Ative o suporte de chaves da API para o seu serviço. Introduza o seguinte comando, em que:
    • MANAGED_SERVICE_NAME especifica o nome do serviço gerido criado quando implementou a API. Pode ver esta propriedade de serviço gerido apresentada com o comando gcloud apigee-gateway apis describe.
    • PROJECT_ID especifica o nome do seu Google Cloud projeto.
    gcloud services enable MANAGED_SERVICE_NAME.apigateway.PROJECT_ID.cloud.goog
    Por exemplo:
    gcloud services enable my-api-123abc456def1.apigateway.my-project.cloud.goog
  2. Modifique a descrição da OpenAPI usada para criar a configuração da API de modo a incluir instruções para aplicar uma política de segurança de validação de chaves da API em todo o tráfego. Adicione o security tipo e securityDefinitions, conforme mostrado:

    OpenAPI 2.0

      # 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://GATEWAY_LOCATION-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"
    O securityDefinition configura a sua API para exigir uma chave da API transmitida como um parâmetro de consulta denominado key quando solicita acesso a todos os caminhos definidos na especificação.

    OpenAPI 3.x

    # openapi-functions.yaml
    openapi: 3.0.4
    info:
      title: API_ID optional-string
      description: Sample API on API Gateway with a Google Cloud Functions backend
      version: 1.0.0
    # Define reusable components in x-google-api-management
    x-google-api-management:
      backend:
        functions_backend:
          address: https://GATEWAY_LOCATION-PROJECT_ID.cloudfunctions.net/helloGET
          pathTranslation: APPEND_PATH_TO_ADDRESS
          protocol: "http/1.1"
    # Apply the backend configuration by referencing it by name. Set at the root so this applies to all operations unless overridden.
    x-google-backend: functions_backend
    components:
    # This section configures basic authentication with an API key.
      securitySchemes:
        google_api_key:
          type: apiKey
          name: x-api-key
          in: header
    security:
      - google_api_key: []
    paths:
      /hello:
        get:
          summary: Greet a user
          operationId: hello
          responses:
            '200':
              description: A successful response
              content:
                application/json:
                  schema:
                    type: string
    O securitySchemes configura a sua API para exigir uma chave da API transmitida como um parâmetro de consulta denominado key quando solicita acesso a todos os caminhos definidos na especificação.
  3. Crie uma nova configuração da API com a especificação OpenAPI modificada através do seguinte comando:
    gcloud api-gateway api-configs create NEW_CONFIG_ID \
    --api=API_ID --openapi-spec=NEW_API_DEFINITION \
    --backend-auth-service-account=SERVICE_ACCOUNT_EMAIL
    Por exemplo:
    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. Execute o seguinte comando para atualizar o gateway existente com a nova configuração da API:
    gcloud api-gateway gateways update GATEWAY_ID \
      --api=API_ID --api-config=NEW_CONFIG_ID \
      --location=GCP_REGION 
    Por exemplo:
    gcloud api-gateway gateways update my-gateway \
      --api=my-api --api-config=my-config-key \
      --location=us-central1 

Teste a chave da API

Depois de criar e implementar a API modificada, experimente fazer um pedido à mesma.

Introduza o seguinte comando curl, em que:

  • DEFAULT_HOSTNAME especifica a parte do nome do anfitrião do URL da gateway implementada.
  • hello é o caminho especificado na configuração da API.
curl https://DEFAULT_HOSTNAME/hello

Por exemplo:

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

Isto deve resultar no seguinte erro:

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.

Agora, introduza o seguinte comando curl, em que:

  • DEFAULT_HOSTNAME especifica a parte do nome do anfitrião do URL da gateway implementada.
  • hello é o caminho especificado na configuração da API.
  • API_KEY especifica a chave da API que criou no passo anterior.
curl https://DEFAULT_HOSTNAME/hello?key=API_KEY

Agora, deve ver Hello World! na resposta da sua API.

Parabéns! Protegeu com êxito o back-end da API com um API Gateway. Agora, pode começar a integrar novos clientes da API gerando chaves da API adicionais.

Limpar

Para evitar incorrer em custos na sua conta do Google Cloud pelos recursos usados neste início rápido, pode:

Em alternativa, também pode eliminar o Google Cloud projeto usado para este tutorial.

O que se segue?