Tìm hiểu cách gọi các hàm Cloud Run đã xác thực

1. Giới thiệu

Tổng quan

Hàm Cloud Run là một giải pháp điện toán gọn nhẹ để nhà phát triển tạo các hàm độc lập, có mục đích đơn lẻ có thể được kích hoạt bằng HTTPS hoặc phản hồi CloudEvents mà không cần quản lý máy chủ hoặc môi trường thời gian chạy. Tìm hiểu thêm về các hàm Cloud Run trong bài đăng trên blog của chúng tôi.

Có hai phương pháp chính để kiểm soát các lệnh gọi đến các hàm Cloud Run: bảo mật quyền truy cập dựa trên danh tính và bảo mật quyền truy cập bằng các biện pháp kiểm soát quyền truy cập dựa trên mạng. Lớp học lập trình này tập trung vào phương pháp đầu tiên và hướng dẫn bạn qua 3 tình huống để bảo mật quyền truy cập dựa trên danh tính để gọi một hàm:

  1. Sử dụng mã thông báo nhận dạng gcloud để gọi một hàm cho mục đích phát triển và kiểm thử cục bộ
  2. Mạo danh tài khoản dịch vụ khi phát triển và kiểm thử cục bộ để sử dụng cùng một thông tin xác thực như trong phiên bản chính thức
  3. Sử dụng thư viện ứng dụng của Google để xử lý việc xác thực cho API Google Cloud, ví dụ: khi một dịch vụ cần gọi một hàm

Kiến thức bạn sẽ học được

  • Cách định cấu hình tính năng xác thực trên một hàm Cloud Run và xác minh tính năng xác thực đã được định cấu hình đúng cách
  • Gọi một hàm đã xác thực từ môi trường phát triển cục bộ bằng cách cung cấp mã thông báo cho danh tính gcloud của bạn
  • Cách tạo tài khoản dịch vụ và cấp cho tài khoản đó vai trò thích hợp để gọi một hàm
  • Cách mạo danh một dịch vụ từ môi trường phát triển cục bộ có các vai trò thích hợp để gọi một hàm

2. Cách thiết lập và các yêu cầu

Điều kiện tiên quyết

  • Bạn đã đăng nhập vào Cloud Console
  • Trước đây, bạn đã triển khai một hàm Cloud Run được kích hoạt bằng HTTP. Xem ví dụ về cách bắt đầu nhanh.
  • (không bắt buộc) Đối với trường hợp thứ 3, lớp học lập trình này sử dụng Node.jsnpm làm ví dụ, nhưng bạn có thể sử dụng bất kỳ môi trường thời gian chạy nào được thư viện ứng dụng Google Auth hỗ trợ.

Kích hoạt Cloud Shell

  1. Trên Cloud Console, hãy nhấp vào Kích hoạt Cloud Shell d1264ca30785e435.png.

84688aa223b1c3a2.pngS

Nếu đây là lần đầu tiên bạn khởi động Cloud Shell, bạn sẽ thấy một màn hình trung gian mô tả về Cloud Shell. Nếu bạn thấy một màn hình trung gian, hãy nhấp vào Tiếp tục.

d95252b003979716.png

Quá trình cấp phép và kết nối với Cloud Shell chỉ mất vài phút.

7833d5e1c5d18f54.png

Máy ảo này được tải sẵn tất cả các công cụ phát triển cần thiết. Phiên bản này cung cấp thư mục gốc có dung lượng ổn định 5 GB và chạy trên Google Cloud, giúp nâng cao đáng kể hiệu suất và khả năng xác thực của mạng. Hầu hết (nếu không nói là) tất cả công việc của bạn trong lớp học lập trình này đều có thể thực hiện bằng trình duyệt.

Sau khi kết nối với Cloud Shell, bạn sẽ thấy mình đã được xác thực và dự án được đặt thành mã dự án của bạn.

  1. Chạy lệnh sau trong Cloud Shell để xác nhận rằng bạn đã được xác thực:
gcloud auth list

Kết quả của lệnh

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

To set the active account, run:
    $ gcloud config set account `ACCOUNT`
  1. Chạy lệnh sau trong Cloud Shell để xác nhận rằng lệnh gcloud biết về dự án của bạn:
gcloud config list project

Kết quả của lệnh

[core]
project = <PROJECT_ID>

Nếu không, bạn có thể đặt giá trị này bằng lệnh sau:

gcloud config set project <PROJECT_ID>

Kết quả của lệnh

Updated property [core/project].

3. Tạo và kiểm thử một hàm Cloud Run đã xác thực

Việc yêu cầu xác thực có nghĩa là nguyên tắc gọi hàm phải có vai trò là Trình gọi Cloud Run; nếu không, hàm sẽ trả về lỗi 403 Forbidden (Cấm). Lớp học lập trình này sẽ cho bạn biết cách cấp các vai trò Invoker (Trình gọi) thích hợp cho một nguyên tắc.

Thiết lập biến môi trường cục bộ cho các lệnh gcloud được đơn giản hoá

Trước tiên, bạn sẽ tạo một vài biến môi trường để cải thiện khả năng đọc của các lệnh gcloud được sử dụng trong lớp học lập trình này.

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

Tạo mã nguồn cho hàm

Mặc dù lớp học lập trình này sử dụng Node.js, nhưng bạn có thể sử dụng bất kỳ môi trường thời gian chạy nào được thư viện ứng dụng Google Auth hỗ trợ.

Trước tiên, hãy tạo một thư mục và chuyển vào thư mục đó.

mkdir auth-function-codelab && cd $_

Sau đó, hãy tạo tệp package.json.

touch package.json

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

Tiếp theo, hãy tạo tệp nguồnindex.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

Tạo hàm được xác thực

Dưới đây là các bước để tạo một hàm đã xác thực cho môi trường thời gian chạy nodejs20. Tuy nhiên, bạn có thể sử dụng bất kỳ môi trường thời gian chạy nào được thư viện ứng dụng Google Auth hỗ trợ.

FUNCTION_NAME=authenticated-function-codelab
ENTRY_POINT=helloWorld

Để triển khai trực tiếp một hàm Cloud Run trên Cloud Run, hãy chạy lệnh sau:

gcloud beta run deploy $FUNCTION_NAME \
      --source . \
      --function helloWorld \
      --region $REGION \
      --no-allow-unauthenticated

sau đó, bạn có thể lưu URL hàm dưới dạng biến môi trường để sử dụng sau.

FUNCTION_URL="$(gcloud run services describe $FUNCTION_NAME --region $REGION --format 'value(status.url)')"

Nếu bạn muốn triển khai dưới dạng Cloud Functions thế hệ 2, hãy sử dụng lệnh sau:

gcloud functions deploy nodejs-http-function \
  --gen2 \
  --runtime=nodejs20 \
  --region=$REGION \
  --source=. \
  --entry-point=helloWorld \
  --trigger-http \
  --no-allow-unauthenticated

sau đó, bạn có thể lưu URL hàm dưới dạng biến môi trường để sử dụng sau.

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

Xác minh hàm yêu cầu xác thực bằng cách cố gắng gọi dưới dạng phương thức gọi ẩn danh

Bạn sẽ gọi hàm mà không cần xác thực để xác minh rằng bạn nhận được lỗi 403 như dự kiến.

Trên một dòng lệnh, hãy chạy lệnh curl sau:

curl -i $FUNCTION_URL

Bạn sẽ thấy kết quả sau:

<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>

Bây giờ, bạn đã sẵn sàng tìm hiểu 3 trường hợp mà bạn có thể gọi Hàm bằng cách cung cấp thông tin xác thực.

4. Tình huống 1: Sử dụng mã thông báo nhận dạng gcloud

Là một nhà phát triển, bạn sẽ muốn có một cách để kiểm thử hàm của mình trong khi phát triển hàm trên máy. Trong phần này, bạn sẽ thực hiện một kiểm thử nhanh để xác minh rằng hàm được xác thực đúng cách bằng danh tính của chính bạn.

Xác minh rằng bạn đã được xác thực bằng gcloud bằng cách chạy lệnh sau:

gcloud auth list

Bạn sẽ thấy một dấu hoa thị bên cạnh danh tính đang hoạt động của mình, ví dụ:

Credentialed Accounts
ACTIVE  ACCOUNT

*       <my_account>@<my_domain.com>

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

Bạn có thể tìm thêm thông tin về cách thiết lập gcloud initđăng nhập bằng tính năng xác thực gcloud trong tài liệu.

Tiếp theo, hãy gọi Hàm và truyền mã thông báo danh tính của bạn vào hàm đó.

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

Bây giờ, bạn sẽ thấy kết quả:

Hello World!

Khắc phục sự cố

Nếu bạn gặp lỗi 403 Forbidden (Cấm), hãy đảm bảo danh tính của bạn có vai trò Trình gọi Cloud Run. Bạn có thể sử dụng bảng điều khiển IAM để xác minh các vai trò được cấp cho một thực thể chính.

Mặc dù việc sử dụng mã thông báo nhận dạng của riêng bạn là một cách nhanh chóng để kiểm thử hàm trong quá trình phát triển, nhưng phương thức gọi của hàm đã xác thực sẽ cần các vai trò thích hợp; nếu không, phương thức gọi sẽ nhận được lỗi 403 Forbidden (Cấm).

Bạn nên tuân thủ nguyên tắc đặc quyền tối thiểu bằng cách giới hạn số lượng danh tính và tài khoản dịch vụ có vai trò gọi hàm. Trong trường hợp tiếp theo, bạn sẽ tìm hiểu cách tạo một tài khoản dịch vụ mới và cấp cho tài khoản đó các vai trò thích hợp để gọi hàm.

5. Tình huống 2: Mạo danh tài khoản dịch vụ

Trong trường hợp này, bạn sẽ giả mạo (tức là giả định quyền của) một tài khoản dịch vụ để gọi một hàm khi phát triển và kiểm thử cục bộ. Bằng cách mạo danh một tài khoản dịch vụ, bạn có thể thử nghiệm chức năng của mình giống như thông tin đăng nhập trong phiên bản chính thức.

Bằng cách này, bạn không chỉ xác minh vai trò mà còn tuân thủ nguyên tắc cấp quyền tối thiểu bằng cách không phải cấp vai trò Người gọi hàm trên đám mây cho các danh tính khác chỉ cho mục đích kiểm thử cục bộ.

Đối với mục đích của lớp học lập trình này, bạn sẽ tạo một tài khoản dịch vụ mới chỉ có các vai trò để gọi hàm mà bạn đã tạo trong lớp học lập trình này.

Tạo tài khoản dịch vụ mới

Trước tiên, bạn sẽ tạo một vài biến môi trường bổ sung để đại diện cho các tài khoản dịch vụ được dùng trong các lệnh gcloud.

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

Tiếp theo, bạn sẽ tạo tài khoản dịch vụ.

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

Đồng thời cấp cho tài khoản dịch vụ vai trò trình gọi Cloud Run:

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

Gọi hàm bằng cách mạo danh tài khoản dịch vụ

Để làm việc này, bạn sẽ mạo danh tài khoản dịch vụ mới tạo bằng cách lấy mã thông báo nhận dạng của tài khoản đó.

Thêm các vai trò bắt buộc để mạo danh

Để mạo danh một tài khoản dịch vụ, tài khoản người dùng của bạn cần có vai trò Trình tạo mã thông báo tài khoản dịch vụ (roles/iam.serviceAccountTokenCreator) để tạo mã thông báo nhận dạng cho tài khoản dịch vụ đó.

Bạn có thể chạy các lệnh sau để cấp vai trò này cho tài khoản người dùng đang hoạt động:

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'

Sử dụng mã thông báo nhận dạng của tài khoản dịch vụ

Hãy chờ vài phút để quyền được áp dụng. Bây giờ, bạn có thể gọi Hàm bằng cách truyền mã thông báo mã nhận dạng của tài khoản dịch vụ.

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

Bạn sẽ thấy như sau:

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. Tình huống 3: Sử dụng thư viện ứng dụng của Google

Trong phần cuối cùng của lớp học lập trình này, bạn sẽ chạy một dịch vụ nhỏ trên máy để tạo mã thông báo nhận dạng cho một tài khoản dịch vụ, sau đó gọi Hàm theo phương thức lập trình bằng thư viện ứng dụng Google AuthThông tin xác thực mặc định của ứng dụng (ADC). Bạn có thể đọc thêm về thư viện ứng dụng của Google trong phần giải thích về thư viện ứng dụng của tài liệu.

Việc sử dụng ADC đặc biệt quan trọng khi bạn muốn viết và kiểm thử Hàm trên máy (ví dụ: trên máy tính xách tay, trong Cloud Shell, v.v.) trong khi tương tác với các tài nguyên khác của Google Cloud (ví dụ: Cloud Storage, API Vision, v.v.) Trong ví dụ này, bạn sẽ thấy cách yêu cầu một dịch vụ gọi một Hàm khác cần xác thực. Để biết thêm thông tin về ADC và quá trình phát triển cục bộ, hãy xem bài đăng trên blog Cách phát triển và kiểm thử Chức năng đám mây trên thiết bị | Blog của Google Cloud

Chạy lệnh gcloud để mạo danh một tài khoản dịch vụ

ADC tự động tìm thông tin xác thực dựa trên môi trường ứng dụng và sử dụng thông tin xác thực đó để xác thực với các API của Google Cloud. Cờ –impersonate-service-account cho phép bạn mạo danh một tài khoản dịch vụ bằng cách sử dụng danh tính của tài khoản đó để xác thực với các API của Google Cloud.

Để mạo danh một tài khoản dịch vụ, bạn có thể chạy lệnh sau:

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

Giờ đây, bạn đang chạy các lệnh gcloud dưới dạng tài khoản dịch vụ đó thay vì danh tính của mình.

Tạo và chạy một dịch vụ để gọi một hàm đã xác thực

Mỗi thời gian chạy đều có thư viện ứng dụng Google Auth riêng mà bạn có thể cài đặt. Lớp học lập trình này hướng dẫn bạn cách tạo và chạy ứng dụng Node.js trên thiết bị.

Sau đây là các bước cho Node.js:

  1. Tạo thư mục mới
mkdir local-dev && cd $_
  1. Tạo ứng dụng Node.js mới
npm init -y
  1. Cài đặt thư viện ứng dụng Xác thực của Google
npm install google-auth-library
  1. Tạo tệp index.js
  2. Truy xuất URL của hàm Cloud Run mà bạn sẽ thêm vào mã của mình ở bước sau.
echo $FUNCTION_URL
  1. Thêm mã sau vào index.js. Hãy nhớ thay đổi biến targetAudience thành URL hàm Cloud Run.

index.js

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

const targetAudience = '<YOUR-CLOUD-RUN-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. Chạy ứng dụng
node index.js

Và bạn sẽ thấy kết quả là "Hello World!" ("Xin chào thế giới!")

Khắc phục sự cố

Nếu bạn gặp lỗi Quyền "iam.serviceAccounts.getOpenIdToken" bị từ chối trên tài nguyên (hoặc quyền này có thể không tồn tại). Vui lòng chờ vài phút để vai trò Người tạo mã thông báo tài khoản dịch vụ được áp dụng.

Nếu bạn gặp lỗi Không thể tìm nạp mã thông báo nhận dạng trong môi trường này, hãy sử dụng GCE hoặc đặt biến môi trường GOOGLE_APPLICATION_CREDENTIALS thành tệp JSON thông tin xác thực tài khoản dịch vụ, có thể bạn đã quên chạy lệnh

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

7. Xin chúc mừng!

Chúc mừng bạn đã hoàn thành lớp học lập trình!

Bạn nên tham khảo tài liệu về cách bảo mật các hàm Cloud Run.

Bạn cũng nên đọc bài đăng trên blog này về phát triển cục bộ bằng các chức năng Cloud Run để tìm hiểu cách phát triển và kiểm thử chức năng Cloud Run trong môi trường phát triển cục bộ.

Nội dung đã đề cập

  • Cách định cấu hình tính năng xác thực trên một hàm Cloud Run và xác minh tính năng xác thực đã được định cấu hình đúng cách
  • Gọi một hàm đã xác thực từ môi trường phát triển cục bộ bằng cách cung cấp mã thông báo cho danh tính gcloud của bạn
  • Cách tạo tài khoản dịch vụ và cấp cho tài khoản đó vai trò thích hợp để gọi một hàm
  • Cách mạo danh một dịch vụ từ môi trường phát triển cục bộ có các vai trò thích hợp để gọi một hàm

8. Dọn dẹp

Để tránh các khoản phí vô tình (ví dụ: Hàm đám mây này vô tình bị gọi nhiều lần hơn mức phân bổ lệnh gọi hàm Cloud Run hằng tháng ở cấp miễn phí), bạn có thể xoá Hàm đám mây hoặc xoá dự án bạn đã tạo ở Bước 2.

Để ngừng mạo danh tài khoản dịch vụ, bạn có thể đăng nhập lại bằng danh tính của mình:

gcloud auth application-default login

Để xoá hàm Cloud Run, hãy truy cập vào Cloud Console của hàm Cloud Run tại https://console.cloud.google.com/functions/ Đảm bảo dự án bạn đã tạo ở bước 2 là dự án hiện được chọn.

Chọn my-authenticated-function mà bạn đã triển khai trước đó. Sau đó, nhấn vào Delete (Xoá).

Nếu chọn xoá toàn bộ dự án, bạn có thể truy cập vào https://console.cloud.google.com/cloud-resource-manager, chọn dự án bạn đã tạo ở Bước 2 rồi chọn Xoá. Nếu xoá dự án, bạn sẽ cần thay đổi các dự án trong SDK trên đám mây. Bạn có thể xem danh sách tất cả dự án hiện có bằng cách chạy gcloud projects list.