Облачные функции в GCP (платформа Google Cloud) – это легкая, нестандартная, безвесочная, и неверная опция для выполнения кода, который запускается событием. Они эквивалентны лямбдасу в AWS (Amazon Web Services) или функции Azure в Microsoft Azure. События, которые вызывают облачную функцию, включают пабы/подпункты, события хранения облаков, такие как создание или удаление объекта хранения и HTTP-запросы.
Как и в случае с любым облачным обслуживанием, вы хотите убедиться, что люди и ресурсы, взаимодействующие с вашей облачной функцией, уполномочены для этого. С помощью Pub/Sub и Cloud Storagers несут ответственность за ограничение, у кого есть возможность вызывать вашу облачную функцию, отложено в IAM (управление идентификацией и доступом), связанным с этими ресурсами, однако с HTTP Triggers вам придется управлять разрешениями, настройки и присвоение одной или нескольких учетной записи Google и/или сервисной учетной записи с авторизацией для вызова вашей облачной функции.
По умолчанию новая облачная функция, созданная в консоли GCP, потребует аутентификации. При развертывании новой облачной функции из gcloud
SDK, вам будет спрашивается, вы хотели бы разрешить ненужные законодательства.
gcloud functions deploy my-new-function ` --entry-point handle_request` --runtime python38 ` --trigger-http Allow unauthenticated invocations of new function [my-new-function]? (y/N)?
Позволяя неактуальным вызовам, вы делаете конечную точку вашей облачной функции доступны в открытый Интернет. Если разрешение неактуальных вызовов является желаемое поведение, вы можете обойти этот вопрос при развертывании через SDK с помощью дополнительного флага - Allow - неаутентифицировано
с Функции GCloud Развертывают
команда. Неопределенные функции облачных функций должны быть исключением; Для большинства случаев использования вы захотите некоторую форму аутентификации и авторизации.
В зависимости от того, кто или что вызывает вашу облачную функцию, процесс настройки аутентификации будет варьироваться, однако существует два требования, общие для всех типов аутентификации:
- Человек или услуга, уполномоченные, чтобы вызвать облачную функцию, должны быть назначены
CloudFunctions.invoker
Роль или какая-то другая роль сCloudFunctions.invoke
разрешение. - Человек или сервис, уполномоченный вызвать облачную функцию, должен отправить токен вместе с HTTP-запросом, чтобы доказать, что они авторизованы, чтобы вызвать функцию облака.
Описание процесса для Все случаи использования выходит за рамки этой статьи. Вместо этого фокус будет настроить аутентификацию для одной функции облака, чтобы вызвать другую функцию облака и на настройке аутентификации локально, чтобы вы могли проверить ваши функции безопасного облака.
Вызов функции к функциям
Перед настройкой аутентификации вам нужно будет запустить функцию, написанную в одном из Поддерживаемые языки С несколькими линиями кода, охватывающих основы ответа на HTTP-запрос. Все пример кода в этом посте было написано в Python, однако принципы будут одинаковыми для всех поддерживаемых языков.
Эта первая облачная функция – это функция вызывающего абонента, и она несет ответственность за проверку начального HTTP-запроса, применяя некоторую бизнес-логику к содержимому этому запросу и, наконец, вызывая вторую функцию облака с помощью HTTP-запроса, который аутентифицирован токеном.
import os import requests from dotenv import load_dotenv load_dotenv() CALLED_CLOUD_FUNCTION_URL = os.getenv('CALLED_CLOUD_FUNCTION_URL') def send_request_to_called_cloud_function(request): request_body = request.get_json(silent=True) if not is_valid_request(request_body): return 'bad request, missing required field "foo"', 400 called_func_request = prepare_called_func_request(request_body) token = request_token() headers = create_request_headers(token) called_func_response = requests.post(CALLED_CLOUD_FUNCTION_URL, json=called_func_request, headers=headers) return called_func_response.text, called_func_response.status_code
Чтобы создать токен, функция облака вызывающего абонента делает HTTP-запрос на свой сервер метаданных.
def request_token(): metadata_server_url = 'http://metadata/computeMetadata/v1/instance/service-accounts/default/identity?audience=' token_request_url = metadata_server_url + CALLED_CLOUD_FUNCTION_URL headers = {'Metadata-Flavor': 'Google'} token_response = requests.get(token_request_url, headers=headers) token = token_response.text return token def create_request_headers(token): headers = { 'content-type': 'application/json', 'authorization': f'bearer {token}' } return headers
Будь то виртуальная машина, функция облака или приложение приложений, все вычислительные ресурсы в GCP имеют сервер, где хранятся соответствующие метаданные по поводу ресурса. Запрос на URL-адрес сервера метаданных в Request_token
Функция проверяет метаданные функции Caller Cloud и проверяя, что учетная запись службы, прикрепленная к нему, уполномочена вызывать предполагаемую аудиторию запроса, называемой функцией облака. Если учетная запись услуг для абонента правильно установлена, ваша функция получит действительный токен для отправки во вторую функцию облака.
Как вы создаете учетную запись службы, которая авторизована, чтобы вызвать облачную функцию? Вы можете либо Создать новую учетную запись услуг Использование консоли или gcloud
SDK и дать ему CloudFunctions.invoker
Роль или вы можете управлять своими ресурсами IAM, используя IAC (инфраструктуру в качестве кода) решением, такого как террафору.
resource "google_service_account" "caller_cloud_function_sa" { project = "my-cloud-function-project" account_id = "caller-cloud-function-sa" display_name = "Caller Cloud Function Service Account" } resource "google_cloud_functions_function" "caller_cloud_function" { project = "my-cloud-function-project" name = "caller-cloud-function" entry_point = "send_request_to_called_cloud_function" runtime = "python38" service_account_email = google_service_account.caller_cloud_function_sa.email trigger_http = true } resource "google_cloudfunctions_function_iam_member" "cloud_function_invoker" { project = google_cloud_functions_function.caller_cloud_function.project region = google_cloud_functions_function.caller_cloud_function.region cloud_function = google_cloud_functions_function.caller_cloud_function.name role = "roles/cloudfunctions.invoker" member = "serviceAccount:${google_service_account.caller_cloud_function_sa.email}" }
Благодаря созданной учетной записи службы и настройкой функции облачного звонящего, чтобы запросить токен с ее сервера метаданных, единственное, что осталось сделать, это запись кода для вызываемой функции облака
from flask import jsonify def respond_to_caller_cloud_function_request(request): request_body = request.get_json(silent=True) if not is_valid_request(request_body): return 'bad request, missing required field "bar"', 400 new_entity = save_request_body(request_body) return jsonify(new_entity), 201
и развернуть оба облачных функций из консоли, gcloud
SDK или через некоторые другие средства, такие как террафор.
# using powershell and the gcloud sdk to deploy both cloud functions gcloud functions deploy caller-cloud-function ` --entry-point send_request_to_called_cloud_function ` --runtime python38 ` --service-account caller-cloud-function-sa@my-cloud-function-project.iam.gserviceaccount.com ` --trigger-http ` --allow-unauthenticated gcloud functions deploy called-cloud-function ` --entry-point respond_to_caller_cloud_function_request ` --runtime python38 ` --trigger-http
Обратите внимание, что функция вызывающего абонента настроен на настройку, чтобы разрешить ненужному доступу. Чтобы сделать этот пример более безопасным, вы либо хотите изменить эту функцию, чтобы использовать одну из других триггеров, либо настроить аутентификацию HTTP также.
Тестирование вашей защищенной функции облака
Теперь, когда вызываемая облачная функция безопасна, тестирование его с локальной машины потребует от вас, чтобы отправить токен вместе с запросом, так как функция облака вызывающего абонента делает.
Чтобы получить токен, сначала убедитесь, что вы вошли в свою учетную запись Google, используя gcloud
SDK, и что у вас есть разрешение, чтобы вызвать облачную функцию. Это требует CloudFunctions.invoker
роль или любая другая роль, которая включает CloudFunctions.invoke
разрешение.
Если вам было присвоено одно из основных ролей редактор
или владелец
У вас будет CloudFunctions.invoke
Разрешение уже, в противном случае вам нужно будет проверить список ролей/разрешений, назначенных на вашу учетную запись и, возможно, запросить роль с CloudFunctions.invoke
Разрешение, добавленное кем-то на проект с возможностью предоставить IAM роли.
Чтобы войти в учетную запись Google, используя gcloud
SDK, используйте команду
gcloud auth login
Это откроет вкладку в вашем браузере, где вам будет предложено войти в систему, используя адрес электронной почты, пароля вашей учетной записи, и любую многофакторную аутентификацию, требуемую настройками безопасности вашей учетной записи.
Как только вы вошли в систему, вы можете запросить токен с помощью команды
gcloud auth print-identity-token
Вы также можете сделать это программно с помощью Python
def request_identity_token(): stream = os.popen('gcloud auth print-identity-token') token = stream.read() return token.strip()
А затем отправьте свой HTTP-запрос таким же образом. Функция вызывающего абонента делает.
import requests from dotenv import load_dotenv load_dotenv() CALLED_CLOUD_FUNCTION_URL = os.getenv('CLOUD_FUNCTION_URL') def send_test_request(): content = {'foo': 'bar'} token = request_identity_token() headers = { 'content-type': 'application/json', 'authorization': f'bearer {token}' response = requests.post(CALLED_CLOUD_FUNCTION_URL, json=content, headers = headers)
При этом вы готовы начать развертывание функций HTTP Cloud, которые требуют аутентификации и тестировать эти функции с вашего локального компьютера. Если ваш корпус на использование требует авторизации для конечных пользователей или какого-либо другого сервиса или ресурса, которые могут варьироваться, но общий процесс присоединения CloudFunctions.invoker
Роль учетной записи Google или учетной записи службы и учет учетной записи пользователя или ресурса создать токен перед вызовом функции, будет прежней.
Оригинал: “https://dev.to/jakewitcher/setting-up-authorization-for-http-cloud-functions-in-gcp-45bc”