Узнайте, как вызывать аутентифицированные облачные функции.

1. Введение

Обзор

Cloud Functions — это легкое вычислительное решение, позволяющее разработчикам создавать одноцелевые автономные функции, которые можно запускать с помощью HTTPS или реагировать на CloudEvents без необходимости управлять сервером или средой выполнения.

Существует два основных подхода к контролю вызовов облачных функций: защита доступа на основе идентификации и защита доступа с использованием средств управления доступом на основе сети . В этой лаборатории кода основное внимание уделяется первому подходу и рассматриваются три сценария обеспечения доступа на основе удостоверения для вызова функции:

  1. Используйте свой токен идентификации gcloud для вызова функции в целях локальной разработки и тестирования.
  2. Олицетворяйте учетную запись службы при локальной разработке и тестировании, чтобы использовать те же учетные данные, что и в рабочей среде.
  3. Используйте клиентские библиотеки Google для аутентификации в Google Cloud API, например, когда службе необходимо вызвать функцию.

Что вы узнаете

  • Как настроить аутентификацию в облачной функции и убедиться, что аутентификация настроена правильно
  • Вызовите аутентифицированную функцию из локальной среды разработки, предоставив токен для вашего удостоверения gcloud.
  • Как создать учетную запись службы и предоставить ей соответствующую роль для вызова функции
  • Как олицетворять службу из локальной среды разработки, имеющую соответствующие роли для вызова функции

2. Настройка и требования

Предварительные условия

  • Вы вошли в облачную консоль
  • Ранее вы развернули облачную функцию 2-го поколения, активируемую HTTP.
  • (необязательно) Для третьего сценария в этой лаборатории кода в качестве примера используются Node.js и npm , но вы можете использовать любую среду выполнения, поддерживаемую клиентскими библиотеками Google Auth .

Активировать Cloud Shell

  1. В Cloud Console нажмите «Активировать Cloud Shell». d1264ca30785e435.png .

84688aa223b1c3a2.png

Если вы запускаете Cloud Shell впервые, вы увидите промежуточный экран с описанием того, что это такое. Если вам был представлен промежуточный экран, нажмите «Продолжить» .

d95252b003979716.png

Подготовка и подключение к Cloud Shell займет всего несколько минут.

7833d5e1c5d18f54.png

Эта виртуальная машина загружена всеми необходимыми инструментами разработки. Он предлагает постоянный домашний каталог объемом 5 ГБ и работает в Google Cloud, что значительно повышает производительность сети и аутентификацию. Большую часть, если не всю, работу в этой лаборатории кода можно выполнить с помощью браузера.

После подключения к Cloud Shell вы увидите, что вы прошли аутентификацию и что для проекта установлен идентификатор вашего проекта.

  1. Выполните следующую команду в Cloud Shell, чтобы подтвердить, что вы прошли аутентификацию:
gcloud auth list

Вывод команды

 Credentialed Accounts
ACTIVE  ACCOUNT
*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Выполните следующую команду в Cloud Shell, чтобы убедиться, что команда gcloud знает о вашем проекте:
gcloud config list project

Вывод команды

[core]
project = <PROJECT_ID>

Если это не так, вы можете установить это с помощью этой команды:

gcloud config set project <PROJECT_ID>

Вывод команды

Updated property [core/project].

3. Создайте и протестируйте аутентифицированную облачную функцию.

Требование аутентификации означает, что принцип, вызывающий функцию, должен иметь роли «Вызов облачных функций» (и «Вызов облачного запуска для 2-го поколения»). в противном случае функция вернет ошибку 403 Forbidden. В этой кодовой лаборатории будет показано , как предоставить принципу соответствующие роли Invoker .

Настройка локальных переменных среды для упрощенных команд gcloud

Сначала вы создадите несколько переменных среды, чтобы улучшить читаемость команд gcloud , используемых в этой лаборатории кода.

REGION=us-central1
PROJECT_ID=$(gcloud config get-value project)

Создайте исходный код для функции

Хотя в этой лаборатории кода используется Node.js, вы можете использовать любую среду выполнения, поддерживаемую клиентскими библиотеками Google Auth.

Сначала создайте каталог и перейдите в него.

mkdir auth-function-codelab && cd $_

Затем создайте файл package.json.

touch package.json

echo '{
  "dependencies": {
    "@google-cloud/functions-framework": "^2.1.0"
  }
}
' > package.json

Затем создайте исходный файл index.js.

touch index.js

echo 'const functions = require("@google-cloud/functions-framework");

functions.http("helloWorld", (req, res) => {
 res.send(`Hello ${req.query.name || req.body.name || "World"}!`);
});' > index.js

Создайте аутентифицированную функцию

Ниже приведены шаги по созданию аутентифицированной функции для среды выполнения nodejs18. Однако вы можете использовать любую среду выполнения, поддерживаемую клиентскими библиотеками Google Auth .

FUNCTION_NAME=authenticated-function-codelab
ENTRY_POINT=helloWorld

gcloud functions deploy $FUNCTION_NAME  \
--gen2 \
--region $REGION \
--source . \
--trigger-http \
--runtime nodejs18 \
--entry-point $ENTRY_POINT \
--no-allow-unauthenticated

а затем вы можете сохранить URL-адрес функции как переменную среды, чтобы использовать ее позже.

FUNCTION_URL="$(gcloud functions describe $FUNCTION_NAME --gen2 --region us-central1 --format='get(serviceConfig.uri)')"

Убедитесь, что функция требует аутентификации, попытавшись вызвать ее как анонимный вызывающий абонент.

Вы вызовете функцию без аутентификации, чтобы убедиться, что вы получили ожидаемую ошибку 403.

Из командной строки выполните следующую команду curl :

curl -i $FUNCTION_URL

Вы увидите следующий результат:

<html><head>
<meta http-equiv="content-type" content="text/html;charset=utf-8">
<title>403 Forbidden</title>
</head>
<body text=#000000 bgcolor=#ffffff>
<h1>Error: Forbidden</h1>
<h2>Your client does not have permission to get URL <code>/</code> from this server.</h2>
<h2></h2>
</body></html>

Теперь вы готовы рассмотреть три сценария, в которых вы можете вызвать свою функцию, предоставив аутентификацию.

4. Сценарий 1. Используйте свой токен идентификации gcloud.

Как разработчику вам понадобится возможность протестировать свою функцию во время ее локальной разработки . В этом разделе вы выполните быстрый тест, чтобы убедиться, что функция правильно аутентифицирована с использованием вашей собственной личности.

Убедитесь, что вы прошли аутентификацию с помощью gcloud , выполнив следующую команду:

gcloud auth list

Вы должны увидеть звездочку рядом с вашей активной личностью, например:

Credentialed Accounts
ACTIVE  ACCOUNT

*       <my_account>@<my_domain.com>

To set the active account, run:
    $ gcloud config set account `ACCOUNT`

Дополнительную информацию о настройке входа в систему gcloud init и gcloud auth можно найти в документации.

Затем вызовите функцию и передайте ей свой идентификационный токен.

curl $FUNCTION_URL -H "Authorization: bearer $(gcloud auth print-identity-token)"

Теперь вы увидите результат:

Hello World!

Поиск неисправностей

Если вы получили сообщение об ошибке 403 Forbidden, убедитесь, что у вашего удостоверения есть роль вызывателя облачных функций или роль вызывающего запуска облачных функций для функций 2-го поколения. Вы можете использовать консоль IAM для проверки ролей, предоставленных участнику.

Хотя использование собственного токена идентификации — это быстрый способ протестировать вашу функцию во время разработки, вызывающей стороне вашей аутентифицированной функции потребуются соответствующие роли; в противном случае вызывающий абонент получит ошибку 403 Forbidden.

Вы захотите следовать принципу наименьших привилегий, ограничив количество удостоверений и учетных записей служб, имеющих роли для вызова функции. В следующем сценарии вы узнаете, как создать новую учетную запись службы и предоставить ей соответствующие роли для вызова функции.

5. Сценарий 2: выдать себя за учетную запись службы

В этом сценарии вы выдаете себя за учетную запись службы (т. е. принимаете на себя ее разрешения) для вызова функции при локальной разработке и тестировании. Выдавая себя за учетную запись службы, вы можете протестировать свою функцию с теми же учетными данными, что и в рабочей среде.

Сделав это, вы не только проверите роли, но и будете следовать принципу наименьших привилегий, поскольку вам не придется предоставлять роль Cloud Function Invoker другим удостоверениям только в целях локального тестирования.

Для целей этой лаборатории кода вы создадите новую учетную запись службы, у которой будут только роли для вызова функции, созданной вами в этой лаборатории кода.

Создать новую учетную запись службы

Сначала вы создадите пару дополнительных переменных среды для представления учетных записей служб, используемых в командах gcloud.

SERVICE_ACCOUNT_NAME="invoke-functions-codelab"
SERVICE_ACCOUNT_ADDRESS=$SERVICE_ACCOUNT_NAME@$PROJECT_ID.iam.gserviceaccount.com

Далее вы создадите учетную запись службы.

gcloud iam service-accounts create $SERVICE_ACCOUNT_NAME \
  --display-name="Cloud Function Authentication codelab"

И предоставьте сервисному аккаунту роль инициатора облачной функции:

gcloud functions add-iam-policy-binding FUNCTION_NAME \
  --region=us-central1 --gen2 \
  --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \
  --role='roles/cloudfunctions.invoker'

Вызовите функцию, олицетворяя учетную запись службы.

Для этого вы выдаете себя за вновь созданную учетную запись службы, получив ее идентификационный токен.

Добавьте необходимые роли для олицетворения

Чтобы олицетворять учетную запись службы, ваша учетная запись пользователя должна иметь роль Создателя токена учетной записи службы (roles/iam.serviceAccountTokenCreator) для создания токена идентификатора для учетной записи службы.

Вы можете запустить следующие команды, чтобы предоставить вашей активной учетной записи пользователя эту роль:

ACCOUNT_EMAIL=$(gcloud auth list --filter=status:ACTIVE --format="value(account)")

gcloud iam service-accounts add-iam-policy-binding $SERVICE_ACCOUNT_ADDRESS  \
  --member user:$ACCOUNT_EMAIL \
  --role='roles/iam.serviceAccountTokenCreator'

Используйте токен идентификатора сервисного аккаунта.

Теперь вы можете вызвать функцию, передав токен идентификатора учетной записи службы.

curl $FUNCTION_URL -H "Authorization: bearer $(gcloud auth print-identity-token --impersonate-service-account $SERVICE_ACCOUNT_ADDRESS)" 

И вы увидите следующее:

WARNING: This command is using service account impersonation. All API calls will be executed as [invoke-functions-codelab@<project-id>.iam.gserviceaccount.com].
Hello World!

6. Сценарий 3. Использование клиентских библиотек Google

В этой последней части лаборатории кода вы локально запустите небольшую службу , чтобы сгенерировать токен идентификатора для учетной записи службы, а затем программно вызовете функцию, используя клиентские библиотеки Google Auth и учетные данные приложения по умолчанию (ADC) . Вы можете прочитать больше о клиентских библиотеках Google в разделе документации, посвященном клиентским библиотекам .

Использование ADC особенно важно, если вы хотите написать и протестировать свою функцию локально (например, на своем ноутбуке, в Cloud Shell и т. д.) при взаимодействии с другими ресурсами Google Cloud (например, Cloud Storage, Vision API и т. д.). В этом примере: вы увидите, как заставить службу вызывать другую функцию, требующую аутентификации. Дополнительную информацию об ADC и локальной разработке см. в записи блога Как разрабатывать и тестировать облачные функции локально | Блог Google Cloud

Запустите команду gcloud, чтобы выдать себя за учетную запись службы.

ADC автоматически находит учетные данные на основе среды приложения и использует эти учетные данные для аутентификации в Google Cloud API. Флаг –impersonate-service-account позволяет вам выдавать себя за учетную запись службы, используя ее идентификатор для аутентификации в Google Cloud API.

Чтобы выдать себя за учетную запись службы, вы можете запустить следующую команду:

gcloud auth application-default login --impersonate-service-account=$SERVICE_ACCOUNT_ADDRESS

Теперь вы запускаете команды gcloud от имени этой учетной записи службы, а не от своей личности.

Создайте и запустите службу для вызова аутентифицированной функции.

Каждая среда выполнения имеет собственную клиентскую библиотеку Google Auth , которую вы можете установить. В этой лаборатории кода вы узнаете, как создать и запустить приложение Node.js локально.

Вот шаги для Node.js:

  1. Создайте новое приложение Node.js.
npm init
  1. Установите клиентскую библиотеку Google Auth.
npm install google-auth-library
  1. Создайте файл index.js
  2. Получите URL-адрес вашей облачной функции, которую вы добавите в свой код на следующем шаге.
echo $FUNCTION_URL
  1. Добавьте следующий код в index.js. Обязательно измените переменную targetAudience на URL-адрес вашей облачной функции.

index.js

// Cloud Functions uses your function's url as the `targetAudience` value

const targetAudience = '<YOUR-CLOUD-FUNCTION-URL>';

// For Cloud Functions, endpoint(`url`) and `targetAudience` should be equal

const url = targetAudience;

const { GoogleAuth } = require('google-auth-library');
const auth = new GoogleAuth();

async function request() {
    console.info(`request ${url} with target audience ${targetAudience}`);

    // this call retrieves the ID token for the impersonated service account
    const client = await auth.getIdTokenClient(targetAudience);

    const res = await client.request({ url });
    console.info(res.data);
}

request().catch(err => {
    console.error(err.message);
    process.exitCode = 1;
});
  1. Запустите приложение
node index.js

И вы должны увидеть результат «Hello World!»

Поиск неисправностей

Если вы видите ошибку «Разрешение iam.serviceAccounts.getOpenIdToken» отклонено для ресурса (или оно может не существовать), подождите несколько минут, пока не распространится роль создателя токена учетной записи службы.

Если вы получили сообщение об ошибке «Невозможно получить токен идентификатора в этой среде», используйте GCE или установите для переменной среды GOOGLE_APPLICATION_CREDENTIALS JSON-файл учетных данных учетной записи службы. Возможно, вы забыли выполнить команду.

gcloud auth application-default login --impersonate-service-account=$SERVICE_ACCOUNT_ADDRESS

7. Поздравляем!

Поздравляем с завершением работы над кодом!

Мы рекомендуем ознакомиться с документацией о том, как защитить Cloud Functions .

Мы также рекомендуем прочитать эту публикацию в блоге о локальной разработке с помощью облачных функций, чтобы узнать, как разрабатывать и тестировать облачную функцию в локальной среде разработки.

Что мы рассмотрели

  • Как настроить аутентификацию в облачной функции и убедиться, что аутентификация настроена правильно
  • Вызовите аутентифицированную функцию из локальной среды разработки, предоставив токен для вашего удостоверения gcloud.
  • Как создать учетную запись службы и предоставить ей соответствующую роль для вызова функции
  • Как олицетворять службу из локальной среды разработки, имеющую соответствующие роли для вызова функции

8. Очистка

Чтобы избежать непреднамеренных расходов (например, эта облачная функция случайно вызывается больше раз, чем ежемесячно выделено количество вызовов облачной функции на уровне бесплатного пользования ), вы можете либо удалить облачную функцию, либо удалить проект, созданный на шаге 2.

Чтобы перестать выдавать себя за учетную запись службы, вы можете повторно войти в систему, используя свою личность:

gcloud auth application-default login

Чтобы удалить облачную функцию, перейдите в облачную консоль облачной функции по адресу https://console.cloud.google.com/functions/. Убедитесь, что проект, созданный вами на шаге 2, является текущим выбранным проектом.

Выберите функцию my-authenticated, которую вы развернули ранее. Затем нажмите «Удалить» .

Если вы решите удалить весь проект, вы можете перейти на https://console.cloud.google.com/cloud-resource-manager , выбрать проект, созданный на шаге 2, и нажать «Удалить». Если вы удалите проект, вам придется изменить проекты в Cloud SDK. Вы можете просмотреть список всех доступных проектов, запустив gcloud projects list .