1. บทนำ
ภาพรวม
Cloud Functions เป็นโซลูชันประมวลผลที่ใช้งานง่ายสำหรับนักพัฒนาแอปในการสร้างฟังก์ชันแบบสแตนด์อโลนวัตถุประสงค์เดียวที่จะทริกเกอร์โดยใช้ HTTPS หรือตอบสนองต่อ CloudEvents ได้โดยไม่ต้องจัดการเซิร์ฟเวอร์หรือสภาพแวดล้อมรันไทม์
วิธีหลักในการควบคุมคำขอไปยัง Cloud Functions มี 2 วิธี ได้แก่ การรักษาการเข้าถึงตามข้อมูลระบุตัวตนและการรักษาความปลอดภัยการเข้าถึงโดยใช้การควบคุมการเข้าถึงตามเครือข่าย Codelab นี้มุ่งเน้นไปที่วิธีการแรกและอธิบายสถานการณ์ต่างๆ 3 อย่างสำหรับการรักษาความปลอดภัยการเข้าถึงตามข้อมูลระบุตัวตนเพื่อเรียกใช้ฟังก์ชัน ดังนี้
- ใช้โทเค็นข้อมูลประจำตัว gcloud เพื่อเรียกใช้ฟังก์ชันสำหรับการพัฒนาภายในและ วัตถุประสงค์ในการทดสอบ
- แอบอ้างเป็นบัญชีบริการเมื่อพัฒนาและทดสอบภายในเพื่อใช้ข้อมูลเข้าสู่ระบบเหมือนกับเวอร์ชันที่ใช้งานจริง
- ใช้ไลบรารีของไคลเอ็นต์ Google เพื่อจัดการการตรวจสอบสิทธิ์กับ Google Cloud APIs เช่น เมื่อบริการจำเป็นต้องเรียกใช้ฟังก์ชัน
สิ่งที่คุณจะได้เรียนรู้
- วิธีกำหนดค่าการตรวจสอบสิทธิ์ใน Cloud Function และยืนยันว่ามีการกำหนดค่าการตรวจสอบสิทธิ์อย่างถูกต้องแล้ว
- เรียกใช้ฟังก์ชันที่ตรวจสอบสิทธิ์แล้วจากสภาพแวดล้อมการพัฒนาในเครื่องโดยมอบโทเค็นสำหรับข้อมูลประจำตัว gcloud ของคุณ
- วิธีสร้างบัญชีบริการและมอบบทบาทที่เหมาะสมในการเรียกใช้ฟังก์ชัน
- วิธีเลียนแบบบริการจากสภาพแวดล้อมการพัฒนาในเครื่องที่มีบทบาทที่เหมาะสมในการเรียกใช้ฟังก์ชัน
2. การตั้งค่าและข้อกำหนด
ข้อกำหนดเบื้องต้น
- คุณเข้าสู่ระบบ Cloud Console แล้ว
- ก่อนหน้านี้คุณได้ทำให้ Cloud Function รุ่นที่ 2 ทริกเกอร์ HTTP ใช้งานได้
- (ไม่บังคับ) สำหรับสถานการณ์ที่ 3 Codelab นี้ใช้ Node.js และ npm เป็นตัวอย่าง แต่คุณสามารถใช้รันไทม์ใดก็ได้ที่ไลบรารีของไคลเอ็นต์ Google Auth รองรับ
เปิดใช้งาน Cloud Shell
- คลิกเปิดใช้งาน Cloud Shell
จาก Cloud Console
หากเริ่มต้นใช้งาน Cloud Shell เป็นครั้งแรก คุณจะเห็นหน้าจอตรงกลางที่อธิบายว่านี่คืออะไร หากระบบแสดงหน้าจอตรงกลาง ให้คลิกต่อไป
การจัดสรรและเชื่อมต่อกับ Cloud Shell ใช้เวลาเพียงไม่กี่นาที
เครื่องเสมือนนี้โหลดด้วยเครื่องมือการพัฒนาทั้งหมดที่จำเป็น โดยมีไดเรกทอรีหลักขนาด 5 GB ถาวรและทำงานใน Google Cloud ซึ่งช่วยเพิ่มประสิทธิภาพของเครือข่ายและการตรวจสอบสิทธิ์ได้อย่างมาก งานส่วนใหญ่ใน Codelab นี้สามารถทำได้โดยใช้เบราว์เซอร์
เมื่อเชื่อมต่อกับ Cloud Shell แล้ว คุณควรเห็นข้อความตรวจสอบสิทธิ์และโปรเจ็กต์ได้รับการตั้งค่าเป็นรหัสโปรเจ็กต์แล้ว
- เรียกใช้คำสั่งต่อไปนี้ใน 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`
- เรียกใช้คำสั่งต่อไปนี้ใน Cloud Shell เพื่อยืนยันว่าคำสั่ง gcloud รู้เกี่ยวกับโปรเจ็กต์ของคุณ
gcloud config list project
เอาต์พุตจากคำสั่ง
[core] project = <PROJECT_ID>
หากไม่ใช่ ให้ตั้งคำสั่งด้วยคำสั่งนี้
gcloud config set project <PROJECT_ID>
เอาต์พุตจากคำสั่ง
Updated property [core/project].
3. สร้างและทดสอบ Cloud Function ที่ตรวจสอบสิทธิ์แล้ว
Codelab นี้ทำตามวิธีการเดียวกันกับการเริ่มต้นใช้งานคอนโซลอย่างรวดเร็วสำหรับ Cloud Functions โดยมีข้อยกเว้นที่สำคัญข้อเดียวคือ ฟังก์ชันจะต้องมีการตรวจสอบสิทธิ์
การต้องมีการตรวจสอบสิทธิ์หมายความว่าหลักการเรียกใช้ฟังก์ชันต้องมีบทบาทผู้เรียกใช้ Cloud Functions (และผู้เรียกใช้ Cloud Run สำหรับรุ่นที่ 2) ไม่เช่นนั้น ฟังก์ชันจะแสดงข้อผิดพลาด 403 Forbidden Codelab นี้จะแสดงวิธีมอบบทบาทผู้เรียกใช้ที่เหมาะสมให้กับหลักการ
สร้างฟังก์ชันที่ตรวจสอบสิทธิ์แล้ว
ขั้นตอนการใช้ Cloud Console มีดังนี้
- ไปที่หน้าภาพรวมฟังก์ชันระบบคลาวด์ แล้วคลิกสร้างฟังก์ชัน
- ในส่วนตัวเลือกสภาพแวดล้อม ให้เลือกรุ่นที่ 2
- ตั้งชื่อฟังก์ชัน my-authenticated-function
- ในช่องการตรวจสอบสิทธิ์ ให้ใช้ค่าเริ่มต้นเป็นต้องมีการตรวจสอบสิทธิ์
- คลิกถัดไป
- คุณเลือกภาษาสำหรับ Codelab นี้ได้
- จากนั้นคลิกทำให้ใช้งานได้
การทำให้ฟังก์ชันใช้งานได้จะใช้เวลาประมาณ 1 นาที
ตั้งค่าตัวแปรสภาพแวดล้อมภายในสำหรับคำสั่ง gcloud แบบง่าย
ก่อนอื่น คุณจะต้องสร้างตัวแปรสภาพแวดล้อม 2-3 รายการเพื่อให้คำสั่ง gcloud
ที่ใช้ใน Codelab นี้อ่านได้ง่ายขึ้น
คุณจะต้องระบุภูมิภาคสำหรับ Function ของคุณ ตัวอย่างนี้ใช้ us-central1
REGION="us-central1"
จากนั้นคุณจะบันทึก URL ฟังก์ชันเป็นตัวแปรสภาพแวดล้อมไว้ใช้ในภายหลังได้
PROJECT_ID=$(gcloud config get-value project) FUNCTION_URL="$(gcloud functions describe my-authenticated-function --gen2 --region us-central1 --format='get(serviceConfig.uri)')"
ยืนยันว่าฟังก์ชันต้องมีการตรวจสอบสิทธิ์โดยพยายามเรียกใช้ในฐานะผู้โทรที่ไม่ระบุตัวตน
คุณจะเรียกใช้ฟังก์ชันโดยไม่มีการตรวจสอบสิทธิ์เพื่อยืนยันว่าคุณได้รับข้อผิดพลาด 403 ที่คาดไว้
จากบรรทัดคำสั่ง ให้เรียกใช้คำสั่ง curl
ต่อไปนี้
curl $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>
ตอนนี้คุณพร้อมที่จะดูสถานการณ์ 3 อย่างที่สามารถเรียกใช้ฟังก์ชันด้วยการระบุการตรวจสอบสิทธิ์
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`
เมื่อยืนยันแล้วว่าคุณใช้ข้อมูลประจำตัวที่ถูกต้อง คุณจะบันทึกอีเมลของบัญชีลงในตัวแปรสภาพแวดล้อม
ACCOUNT_EMAIL=$(gcloud auth list --filter=status:ACTIVE --format="value(account)")
ดูข้อมูลเพิ่มเติมเกี่ยวกับการตั้งค่า gcloud init และ gcloud authlogin ได้ในเอกสาร
ถัดไป ให้เรียกใช้ฟังก์ชันแล้วส่งโทเค็นข้อมูลประจำตัวของคุณ
curl $FUNCTION_URL -H "Authorization: bearer $(gcloud auth print-identity-token)"
ตอนนี้คุณจะเห็นผลลัพธ์:
Hello World!
การแก้ปัญหา
หากได้รับข้อผิดพลาด 403 Forbidden โปรดตรวจสอบว่าตัวตนของคุณมีบทบาทผู้เรียกใช้ Cloud Functions หรือบทบาทผู้เรียกใช้ Cloud Run สำหรับฟังก์ชันรุ่นที่ 2 คุณใช้คอนโซล IAM เพื่อยืนยันบทบาทที่กำหนดให้กับผู้ใช้หลักได้
แม้ว่าการใช้โทเค็นข้อมูลประจำตัวของคุณเองจะช่วยให้ทดสอบฟังก์ชันในระหว่างการพัฒนาได้อย่างรวดเร็ว แต่ผู้เรียกใช้ฟังก์ชันที่ได้รับการตรวจสอบสิทธิ์จะต้องมีบทบาทที่เหมาะสม ไม่เช่นนั้น ผู้โทรจะได้รับข้อผิดพลาด 403 Forbidden
คุณจะต้องปฏิบัติตามหลักของสิทธิ์ขั้นต่ำโดยการจำกัดจำนวนข้อมูลประจำตัวและบัญชีบริการที่มีบทบาทที่จะเรียกใช้ฟังก์ชัน
สร้างบัญชีบริการใหม่และมอบบทบาทที่จำเป็น
5. สถานการณ์ที่ 2: แอบอ้างบัญชีบริการ
ในสถานการณ์นี้ คุณจะแอบอ้างเป็นบุคคลอื่น (เช่น อ้างสิทธิ์ใน) บัญชีบริการเพื่อเรียกใช้ฟังก์ชันเมื่อพัฒนาและทดสอบภายใน เมื่อแอบอ้างเป็นบัญชีบริการ คุณจะทดสอบฟังก์ชันได้เหมือนกับที่ใช้ในเวอร์ชันที่ใช้งานจริง
การทำเช่นนี้จะไม่เพียงไม่เพียงยืนยันบทบาท แต่ยังทำตามหลักการให้สิทธิ์ขั้นต่ำโดยไม่ต้องมอบบทบาทผู้เรียกใช้ Cloud Function ให้กับข้อมูลประจำตัวอื่นๆ เพื่อการทดสอบภายในโดยเฉพาะด้วย
เพื่อจุดประสงค์ของ Codelab นี้ คุณจะสร้างบัญชีบริการใหม่ที่มีเฉพาะบทบาทในการเรียกใช้ฟังก์ชันที่คุณสร้างไว้ใน Codelab นี้
สร้างบัญชีบริการใหม่
ก่อนอื่น คุณจะต้องสร้างตัวแปรสภาพแวดล้อมเพิ่มเติม 2 รายการเพื่อแสดงบัญชีบริการที่ใช้ในคำสั่ง 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"
และมอบบทบาทผู้เรียกใช้ Cloud Function ให้กับบัญชีบริการ
gcloud functions add-iam-policy-binding my-authenticated-function \ --region=us-central1 --gen2 \ --member serviceAccount:$SERVICE_ACCOUNT_ADDRESS \ --role='roles/cloudfunctions.invoker'
เรียกใช้ฟังก์ชันโดยการแอบอ้างบัญชีบริการ
สำหรับกรณีนี้ คุณจะสวมบทบาทเป็นบัญชีบริการที่สร้างขึ้นใหม่ด้วยการรับโทเค็นรหัสของบัญชีดังกล่าว
เพิ่มบทบาทที่จำเป็นสำหรับการแอบอ้างเป็นบุคคลอื่น
สำหรับการแอบอ้างบัญชีบริการ บัญชีผู้ใช้ของคุณต้องมีบทบาทผู้สร้างโทเค็นบัญชีบริการ (roles/iam.serviceAccountTokenCreator) เพื่อสร้างโทเค็นรหัสสำหรับบัญชีบริการ
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
สำหรับส่วนสุดท้ายของ Codelab คุณจะต้องเรียกใช้บริการขนาดเล็กในเครื่องเพื่อสร้างโทเค็นรหัสสำหรับบัญชีบริการ จากนั้นเรียกใช้ฟังก์ชันแบบเป็นโปรแกรมโดยใช้ไลบรารีของไคลเอ็นต์ Google Auth และข้อมูลเข้าสู่ระบบเริ่มต้นของแอปพลิเคชัน (ADC) คุณสามารถอ่านเพิ่มเติมเกี่ยวกับไลบรารีของไคลเอ็นต์ Google ได้ในส่วนคำอธิบายไลบรารีของไคลเอ็นต์ของเอกสาร
การใช้ ADC มีความสำคัญอย่างยิ่งเมื่อคุณต้องการเขียนและทดสอบฟังก์ชันภายในเครื่อง (เช่น บนแล็ปท็อป ใน Cloud Shell ฯลฯ) ขณะโต้ตอบกับทรัพยากรอื่นๆ ของ Google Cloud (เช่น Cloud Storage, Vision API ฯลฯ) ในตัวอย่างนี้ คุณจะเห็นวิธีที่บริการหนึ่งๆ จะเรียกใช้ฟังก์ชันอื่นที่ต้องมีการตรวจสอบสิทธิ์ ดูข้อมูลเพิ่มเติมเกี่ยวกับ ADC และการพัฒนาภายในได้ที่บล็อกโพสต์วิธีพัฒนาและทดสอบ Cloud Functions ในเครื่อง | บล็อก Google Cloud
เรียกใช้คำสั่ง gcloud เพื่อแอบอ้างบัญชีบริการ
ADC จะค้นหาข้อมูลเข้าสู่ระบบโดยอัตโนมัติตามสภาพแวดล้อมของแอปพลิเคชัน และจะใช้ข้อมูลเข้าสู่ระบบเหล่านั้นเพื่อตรวจสอบสิทธิ์ Google Cloud API แฟล็ก –impersonate-service-account ช่วยให้คุณแอบอ้างเป็นบัญชีบริการได้ โดยใช้ข้อมูลระบุตัวตนของบัญชีนั้นในการตรวจสอบสิทธิ์กับ Google Cloud APIs
หากต้องการแอบอ้างเป็นบัญชีบริการ ให้เรียกใช้คำสั่งต่อไปนี้
gcloud auth application-default login --impersonate-service-account=$SERVICE_ACCOUNT_ADDRESS
ตอนนี้คุณกำลังเรียกใช้คำสั่ง gcloud เป็นบัญชีบริการนั้น แทนที่จะเป็นข้อมูลระบุตัวตนของคุณ
สร้างและเรียกใช้บริการเพื่อเรียกใช้ฟังก์ชันที่ตรวจสอบสิทธิ์แล้ว
รันไทม์แต่ละรายการจะมีไลบรารีของไคลเอ็นต์ Google Auth ของตนเองซึ่งคุณติดตั้งได้ Codelab นี้จะแนะนำวิธีสร้างและเรียกใช้แอป Node.js ในเครื่อง
ขั้นตอนสำหรับ Node.js มีดังนี้
- สร้างแอป Node.js ใหม่
npm init
- ติดตั้งไลบรารีของไคลเอ็นต์ Google Auth
npm install google-auth-library
- สร้างไฟล์
index.js
- ดึงข้อมูล URL ของ Cloud Function ซึ่งจะเพิ่มลงในโค้ดในขั้นตอนต่อไปนี้
echo $FUNCTION_URL
- เพิ่มโค้ดต่อไปนี้ลงในindex.js อย่าลืมเปลี่ยนตัวแปร targetAudience เป็น URL ของ Cloud Function
ดัชนี.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;
});
- เรียกใช้แอป
node index.js
และคุณควรจะเห็นผลลัพธ์ " Hello World!"
การแก้ปัญหา
หากคุณเห็นข้อผิดพลาด Permissions "iam.serviceAccounts.getOpenIdToken" ปฏิเสธในทรัพยากร (หรืออาจไม่มีอยู่) โปรดรอสักครู่เพื่อให้บทบาทผู้สร้างโทเค็นบัญชีบริการมีผล
หากคุณได้รับข้อผิดพลาด ไม่สามารถดึงข้อมูลโทเค็นรหัสในสภาพแวดล้อมนี้ ให้ใช้ GCE หรือตั้งค่าตัวแปรสภาพแวดล้อม GOOGLE_APPLICATION_CREDENTIALS เป็นไฟล์ JSON ของข้อมูลเข้าสู่ระบบของบัญชีบริการ คุณอาจลืมเรียกใช้คำสั่ง
gcloud auth application-default login --impersonate-service-account=$SERVICE_ACCOUNT_ADDRESS
7. ยินดีด้วย
ขอแสดงความยินดีที่เรียน Codelab จนจบ
เราขอแนะนำให้อ่านเอกสารเกี่ยวกับวิธีรักษาความปลอดภัยของ Cloud Functions
นอกจากนี้ เราขอแนะนำบล็อกโพสต์นี้เกี่ยวกับการพัฒนาภายในด้วยฟังก์ชันระบบคลาวด์ เพื่อดูวิธีพัฒนาและทดสอบ Cloud Function ในสภาพแวดล้อมของนักพัฒนาซอฟต์แวร์ภายใน
หัวข้อที่ครอบคลุม
- วิธีกำหนดค่าการตรวจสอบสิทธิ์ใน Cloud Function และยืนยันว่ามีการกำหนดค่าการตรวจสอบสิทธิ์อย่างถูกต้องแล้ว
- เรียกใช้ฟังก์ชันที่ตรวจสอบสิทธิ์แล้วจากสภาพแวดล้อมการพัฒนาในเครื่องโดยมอบโทเค็นสำหรับข้อมูลประจำตัว gcloud ของคุณ
- วิธีสร้างบัญชีบริการและมอบบทบาทที่เหมาะสมในการเรียกใช้ฟังก์ชัน
- วิธีเลียนแบบบริการจากสภาพแวดล้อมการพัฒนาในเครื่องที่มีบทบาทที่เหมาะสมในการเรียกใช้ฟังก์ชัน
8. ล้างข้อมูล
เพื่อหลีกเลี่ยงการเรียกเก็บเงินที่ไม่ตั้งใจ (เช่น มีการเรียกใช้ Cloud Function โดยไม่ได้ตั้งใจมากกว่าการจัดสรรการเรียกใช้ Cloud Function รายเดือนในรุ่นฟรี) คุณจะลบ Cloud Function หรือลบโปรเจ็กต์ที่สร้างไว้ในขั้นตอนที่ 2 ก็ได้
หากต้องการหยุดแอบอ้างบัญชีบริการ ให้เข้าสู่ระบบอีกครั้งโดยใช้ข้อมูลประจำตัวโดยทำดังนี้
gcloud auth application-default login
หากต้องการลบ Cloud Function ให้ไปที่ Cloud Function ใน Cloud Console ที่ https://console.cloud.google.com/functions/ ตรวจสอบว่าโปรเจ็กต์ที่คุณสร้างในขั้นตอนที่ 2 เป็นโปรเจ็กต์ที่เลือกไว้ในปัจจุบัน
เลือก my-authenticated-function ที่คุณทำให้ใช้งานได้ก่อนหน้านี้ จากนั้นกดลบ
หากเลือกลบทั้งโปรเจ็กต์ ให้ไปที่ https://console.cloud.google.com/cloud-resource-manager เลือกโปรเจ็กต์ที่คุณสร้างในขั้นตอนที่ 2 แล้วเลือกลบ หากลบโปรเจ็กต์ คุณจะต้องเปลี่ยนโปรเจ็กต์ใน Cloud SDK คุณสามารถดูรายการโปรเจ็กต์ที่ใช้ได้ทั้งหมดโดยเรียกใช้ gcloud projects list