การใช้ OAuth 2.0 สำหรับแอปพลิเคชันระหว่างเซิร์ฟเวอร์กับเซิร์ฟเวอร์

"ยยยยย เพราะโสูงวโสูงโสูงโสูงโสูงโสูงะโน้อยวแยกตามวสูงวสูงวสูงสูงสูงฮสูงฮสูงฮสูงที่คุณต้องสูงที่คุณต้องที่คุณต้องที่ตั้งไว้ที่คุณต้องส่ง ซึ่งส่ง ซึ่งส่งผู้ที่ผู้ที่ข้อความที่ใช้งานได้ที่ใช้งานได้ที่ใช้งานได้ที่ใช้งานได้ที่ประกอบด้วยทุกทุกเครื่องมือว่าเนอุปกรณ์คําว่า ว่าของคุณและของคุณและว่าเว่าเว่าว่าว่าว่าว่าว่าลุข้อความข้อความอีกอีกอีกชื่อง่ายๆง่ายๆง่ายๆง่ายๆง่ายๆเนเนเนเนง่ายๆง่ายๆง่ายๆ คุณก็ง่ายๆ คุณก็การติดต่อแบการติดต่อ คุณก็ ถ้าคุณโฆษณาง่ายๆ

ระบบ Google OAuth 2.0 รองรับการโต้ตอบแบบเซิร์ฟเวอร์ต่อเซิร์ฟเวอร์ เช่น การโต้ตอบระหว่างเว็บแอปพลิเคชันและบริการของ Google สําหรับกรณีนี้ คุณจะต้องมีบัญชีบริการซึ่งเป็นบัญชีที่เป็นของแอปพลิเคชันของคุณ ไม่ใช่ของผู้ใช้แต่ละราย แอปพลิเคชันของคุณเรียกใช้ Google APIs ในนามบัญชีบริการนั้น ผู้ใช้จึงไม่มีส่วนเกี่ยวข้องโดยตรง สถานการณ์นี้บางครั้งเรียกว่า "OAuth แบบสองทาง" หรือ "2LO" (คําว่า "OAuth แบบ 3 ทาง" ที่เกี่ยวข้องหมายถึงสถานการณ์ที่แอปพลิเคชันของคุณเรียก Google API ในนามของผู้ใช้ปลายทาง และบางครั้งต้องได้รับคํายินยอมจากผู้ใช้)

โดยทั่วไป แอปพลิเคชันจะใช้บัญชีบริการเมื่อแอปพลิเคชันใช้ Google APIs เพื่อทํางานกับข้อมูลของตนเอง ไม่ใช่ข้อมูลของผู้ใช้ เช่น แอปพลิเคชันที่ใช้ Google Cloud Datastore เพื่อความต่อเนื่องของข้อมูลจะใช้บัญชีบริการในการตรวจสอบสิทธิ์การเรียกไปยัง Google Cloud Datastore API

นอกจากนี้ ผู้ดูแลระบบโดเมน Google Workspace ยังให้สิทธิ์ทั่วทั้งโดเมนบัญชีบริการเพื่อเข้าถึงข้อมูลผู้ใช้ในนามของผู้ใช้ในโดเมนได้อีกด้วย

เอกสารนี้จะอธิบายวิธีที่แอปพลิเคชันดําเนินการขั้นตอน OAuth 2.0 แบบเซิร์ฟเวอร์ต่อเซิร์ฟเวอร์ได้โดยใช้ไลบรารีของไคลเอ็นต์ Google APIs (แนะนํา) หรือ HTTP

ภาพรวม

หากต้องการรองรับการโต้ตอบระหว่างเซิร์ฟเวอร์กับเซิร์ฟเวอร์ ก่อนอื่นให้สร้างบัญชีบริการสําหรับโปรเจ็กต์ของคุณใน API Consoleหากต้องการเข้าถึงข้อมูลผู้ใช้สําหรับผู้ใช้ในบัญชี Google Workspace ให้มอบสิทธิ์การเข้าถึงบัญชีบริการทั่วทั้งโดเมน

จากนั้นแอปพลิเคชันจะเตรียมเรียก API ที่ได้รับอนุญาตโดยใช้ข้อมูลเข้าสู่ระบบของบัญชีบริการเพื่อขอโทเค็นเพื่อการเข้าถึงจากเซิร์ฟเวอร์การตรวจสอบสิทธิ์ OAuth 2.0

สุดท้าย แอปพลิเคชันของคุณสามารถใช้โทเค็นเพื่อการเข้าถึงเพื่อเรียก Google APIs

การสร้างบัญชีบริการ

ข้อมูลเข้าสู่ระบบของบัญชีบริการจะมีอีเมลที่สร้างขึ้นไม่ซ้ํากันและคู่คีย์สาธารณะ/ส่วนตัวอย่างน้อย 1 คู่ หากเปิดใช้การมอบสิทธิ์ทั่วทั้งโดเมน รหัสไคลเอ็นต์จะเป็นส่วนหนึ่งของข้อมูลเข้าสู่ระบบของบัญชีบริการด้วย

หากแอปพลิเคชันของคุณทํางานบน Google App Engine จะมีการตั้งค่าบัญชีโดยอัตโนมัติเมื่อคุณสร้างโปรเจ็กต์

หากแอปพลิเคชันของคุณทํางานบน Google Compute Engine จะมีการตั้งค่าบัญชีโดยอัตโนมัติเมื่อคุณสร้างโปรเจ็กต์ แต่คุณต้องระบุขอบเขตที่แอปพลิเคชันต้องการเข้าถึงเมื่อสร้างอินสแตนซ์ Google Compute Engine ดูข้อมูลเพิ่มเติมได้ที่การเตรียมอินสแตนซ์เพื่อใช้บัญชีบริการ

หากแอปพลิเคชันของคุณไม่ทํางานบน Google App Engine หรือ Google Compute Engine คุณจะต้องได้รับข้อมูลรับรองเหล่านี้ใน Google API Consoleหากต้องการสร้างข้อมูลเข้าสู่ระบบของบัญชีบริการ หรือดูข้อมูลรับรองสาธารณะที่สร้างไว้แล้ว ให้ทําดังนี้

ขั้นแรก สร้างบัญชีบริการ:

  1. เปิด Service accounts page
  2. If prompted, select a project, or create a new one.
  3. คลิก สร้างบัญชีบริการ
  4. ภายใต้ รายละเอียดบัญชีบริการ ให้พิมพ์ชื่อ ID และคำอธิบายสำหรับบัญชีบริการ จากนั้นคลิก สร้างและดำเนิน การต่อ
  5. ทางเลือก: ภายใต้ ให้สิทธิ์การเข้าถึงบัญชีบริการนี้กับโครงการ เลือกบทบาท IAM เพื่อมอบให้กับบัญชีบริการ
  6. คลิกดำเนินการ ต่อ
  7. ไม่บังคับ: ภายใต้ ให้สิทธิ์ผู้ใช้เข้าถึงบัญชีบริการนี้ ให้ เพิ่มผู้ใช้หรือกลุ่มที่ได้รับอนุญาตให้ใช้และจัดการบัญชีบริการ
  8. คลิก เสร็จสิ้น

จากนั้น สร้างรหัสบัญชีบริการ:

  1. คลิกที่อยู่อีเมลสำหรับบัญชีบริการที่คุณสร้างขึ้น
  2. คลิกแท็บ คีย์
  3. ในรายการดรอปดาวน์ เพิ่มคีย์ เลือก สร้างคีย์ใหม่
  4. คลิก สร้าง

คู่คีย์สาธารณะ/ส่วนตัวใหม่ของคุณถูกสร้างขึ้นและดาวน์โหลดลงในเครื่องของคุณ มันทำหน้าที่เป็นสำเนาเดียวของคีย์ส่วนตัว คุณมีหน้าที่รับผิดชอบในการจัดเก็บอย่างปลอดภัย หากคุณทำคู่คีย์นี้หาย คุณจะต้องสร้างคู่คีย์ใหม่

คุณกลับไปที่ API Console ได้ทุกเมื่อเพื่อดูอีเมล ลายนิ้วมือคีย์สาธารณะ และข้อมูลอื่นๆ หรือเพื่อสร้างคู่คีย์สาธารณะ/ส่วนตัวเพิ่มเติม ดูรายละเอียดเพิ่มเติมเกี่ยวกับข้อมูลเข้าสู่ระบบของบัญชีบริการใน API Consoleได้ที่บัญชีบริการในไฟล์ความช่วยเหลือ API Console

จดบันทึกอีเมลของบัญชีบริการและเก็บไฟล์คีย์ส่วนตัวของบัญชีบริการไว้ในตําแหน่งที่แอปพลิเคชันเข้าถึงได้ แอปพลิเคชันของคุณต้องการให้แอปพลิเคชันเหล่านั้นทําการเรียก API ที่ได้รับอนุญาต

การมอบสิทธิ์ทั่วทั้งโดเมนให้กับบัญชีบริการ

ผู้ดูแลระบบ Workspace ขององค์กรสามารถให้สิทธิ์แอปพลิเคชันในการเข้าถึงข้อมูลผู้ใช้ Workspace ในนามของผู้ใช้ในโดเมน Google Workspace ได้โดยใช้บัญชี Google Workspace เช่น แอปพลิเคชันที่ใช้ Google Calendar API เพื่อเพิ่มกิจกรรมลงในปฏิทินของผู้ใช้ทุกคนในโดเมน Google Workspace จะใช้บัญชีบริการเพื่อเข้าถึง Google Calendar API ในนามของผู้ใช้ บางครั้งการให้สิทธิ์บัญชีบริการเพื่อเข้าถึงข้อมูลในนามของผู้ใช้ในโดเมนจะเรียกว่า "การมอบสิทธิ์ทั่วทั้งโดเมน" ให้กับบัญชีบริการ

หากต้องการมอบสิทธิ์ทั่วทั้งโดเมนให้กับบัญชีบริการ ผู้ดูแลระบบขั้นสูงของโดเมน Google Workspace ต้องทําตามขั้นตอนต่อไปนี้

  1. จาก คอนโซลผู้ดูแลระบบของโดเมน Google Workspace ให้ไปที่เมนูหลัก > ความปลอดภัย > การเข้าถึงและการควบคุมข้อมูล > การควบคุม API
  2. ในแผงการมอบสิทธิ์ทั่วทั้งโดเมน ให้เลือกจัดการการมอบสิทธิ์ทั่วทั้งโดเมน
  3. คลิกเพิ่มใหม่
  4. กรอกรหัสไคลเอ็นต์ของบัญชีบริการในช่องรหัสไคลเอ็นต์ ดูรหัสไคลเอ็นต์ของบัญชีบริการได้ใน Service accounts page
  5. ในช่องขอบเขต OAuth (คั่นด้วยเครื่องหมายจุลภาค) ให้ป้อนรายการขอบเขตที่แอปพลิเคชันของคุณควรได้รับสิทธิ์เข้าถึง เช่น หากแอปพลิเคชันของคุณต้องการเข้าถึง Google Drive API และ Google Calendar API แบบทั้งโดเมน ให้ป้อน https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/calendar
  6. คลิกให้สิทธิ์

แอปพลิเคชันของคุณมีสิทธิ์เรียก API เป็นผู้ใช้ในโดเมน Workspace ของคุณ (เพื่อ "สวมบทบาท" ผู้ใช้) เมื่อคุณเตรียมที่จะเรียกใช้ API ที่มอบสิทธิ์นี้ คุณจะระบุตัวผู้ใช้เพื่อแอบอ้างอย่างชัดแจ้ง

กําลังเตรียมเรียก API ที่มอบสิทธิ์

Java

หลังจากที่ได้อีเมลไคลเอ็นต์และคีย์ส่วนตัวจาก API Consoleแล้ว ให้ใช้ไลบรารีของไคลเอ็นต์ Google APIs สําหรับ Java เพื่อสร้างออบเจ็กต์ GoogleCredential จากข้อมูลรับรองของบัญชีบริการและขอบเขตที่แอปพลิเคชันต้องการเข้าถึง เช่น

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.services.sqladmin.SQLAdminScopes;

// ...

GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"))
    .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN));

หากพัฒนาแอปใน Google Cloud Platform คุณอาจใช้ข้อมูลเข้าสู่ระบบเริ่มต้นของแอปพลิเคชันแทนซึ่งจะทําให้กระบวนการง่ายขึ้น

มอบสิทธิ์ทั่วทั้งโดเมน

หากคุณมอบสิทธิ์เข้าถึงทั่วทั้งบัญชีบริการให้กับบัญชีบริการและต้องการแอบอ้างเป็นบัญชีผู้ใช้ ให้ระบุอีเมลของบัญชีผู้ใช้ด้วยเมธอด createDelegated ของออบเจ็กต์ GoogleCredential เช่น

GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"))
    .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN))
    .createDelegated("workspace-user@example.com");

โค้ดด้านบนใช้ออบเจ็กต์ GoogleCredential เพื่อเรียกเมธอด createDelegated() อาร์กิวเมนต์ของเมธอด createDelegated() ต้องเป็นของผู้ใช้บัญชี Workspace ของคุณ โค้ดที่ส่งคําขอจะใช้ข้อมูลเข้าสู่ระบบนี้เพื่อเรียกใช้ Google API โดยใช้บัญชีบริการของคุณ

Python

หลังจากได้รับที่อยู่อีเมลและคีย์ส่วนตัวของไคลเอ็นต์จาก API Consoleแล้ว ให้ใช้ไลบรารีของไคลเอ็นต์ Google APIs สําหรับ Python เพื่อทําตามขั้นตอนต่อไปนี้

  1. สร้างออบเจ็กต์ Credentials จากข้อมูลรับรองของบัญชีบริการและขอบเขตที่แอปพลิเคชันต้องการเข้าถึง ตัวอย่างเช่น
    from google.oauth2 import service_account
    
    SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin']
    SERVICE_ACCOUNT_FILE = '/path/to/service.json'
    
    credentials = service_account.Credentials.from_service_account_file(
            SERVICE_ACCOUNT_FILE, scopes=SCOPES)

    หากพัฒนาแอปใน Google Cloud Platform คุณอาจใช้ข้อมูลเข้าสู่ระบบเริ่มต้นของแอปพลิเคชันแทนซึ่งจะทําให้กระบวนการง่ายขึ้น

  2. มอบสิทธิ์ทั่วทั้งโดเมน

    หากคุณมอบสิทธิ์ทั่วทั้งโดเมนให้กับบัญชีบริการแล้วและต้องการแอบอ้างเป็นบัญชีผู้ใช้ ให้ใช้วิธีการ with_subject ของออบเจ็กต์ ServiceAccountCredentials ที่มีอยู่ เช่น

    delegated_credentials = credentials.with_subject('user@example.org')

ใช้ออบเจ็กต์ข้อมูลเข้าสู่ระบบเพื่อเรียกใช้ Google API ในแอปพลิเคชัน

HTTP/REST

หลังจากได้รับรหัสไคลเอ็นต์และคีย์ส่วนตัวจาก API Consoleแล้ว แอปพลิเคชันจะต้องทําตามขั้นตอนต่อไปนี้

  1. สร้าง JSON Web Token (JWT, ออกเสียง, "jot") ซึ่งประกอบด้วยส่วนหัว ชุดการอ้างสิทธิ์ และลายเซ็น
  2. ขอโทเค็นเพื่อการเข้าถึงจากเซิร์ฟเวอร์การให้สิทธิ์ของ Google OAuth 2.0
  3. จัดการการตอบสนอง JSON ที่ Authorization Server แสดงผล

หัวข้อต่อไปนี้จะอธิบายวิธีดําเนินการตามขั้นตอนเหล่านี้

หากการตอบกลับมีโทเค็นเพื่อการเข้าถึง คุณจะใช้โทเค็นเพื่อการเข้าถึงเพื่อเรียกใช้ Google API ได้ (หากการตอบกลับไม่มีโทเค็นเพื่อการเข้าถึง คําขอ JWT และโทเค็นอาจอยู่ในรูปแบบที่ไม่ถูกต้อง หรือบัญชีบริการอาจไม่มีสิทธิ์เข้าถึงขอบเขตที่ขอ)

เมื่อโทเค็นเพื่อการเข้าถึงหมดอายุ แอปพลิเคชันจะสร้าง JWT อื่น จากนั้นลงนาม และขอโทเค็นเพื่อการเข้าถึงอื่น

แอปพลิเคชันเซิร์ฟเวอร์จะใช้ JWT เพื่อขอโทเค็นจากเซิร์ฟเวอร์การให้สิทธิ์ของ Google จากนั้นใช้โทเค็นนั้นเรียกใช้ปลายทาง Google API ไม่มีผู้ใช้ปลายทางเกี่ยวข้อง

เนื้อหาที่เหลือของส่วนนี้จะอธิบายเกี่ยวกับรายละเอียดในการสร้าง JWT, การลงนาม JWT, การสร้างคําขอโทเค็นการเข้าถึง และการจัดการการตอบกลับ

การสร้าง JWT

JWT ประกอบด้วย 3 ส่วน ได้แก่ ส่วนหัว ชุดการอ้างสิทธิ์ และลายเซ็น ส่วนหัวและชุดการอ้างสิทธิ์คือออบเจ็กต์ JSON ออบเจ็กต์ JSON เหล่านี้ได้รับการจัดลําดับให้เป็น ไบต์ UTF-8 แล้วเข้ารหัสโดยใช้การเข้ารหัส Base64url การเข้ารหัสนี้มีความยืดหยุ่นต่อการเปลี่ยนแปลงการเข้ารหัสเนื่องจากมีการดําเนินการเข้ารหัสซ้ําๆ ส่วนหัว ชุดการอ้างสิทธิ์ และลายเซ็นจะเชื่อมติดกันด้วยอักขระจุด (.)

JWT ประกอบด้วยข้อมูลดังนี้

{Base64url encoded header}.{Base64url encoded claim set}.{Base64url encoded signature}

สตริงฐานสําหรับลายเซ็นมีดังนี้

{Base64url encoded header}.{Base64url encoded claim set}
การสร้างส่วนหัว JWT

ส่วนหัวประกอบด้วย 3 ช่องที่ระบุอัลกอริทึมการลงชื่อ รูปแบบของการยืนยัน และ [รหัสคีย์ของคีย์บัญชีบริการ](https://cloud.google.com/iam/docs/reference/rest/v1/projects.serviceAccounts.keys) ที่ใช้ลงนาม JWT จําเป็นต้องระบุอัลกอริทึมและรูปแบบ และแต่ละช่องมีเพียงค่าเดียว เมื่อมีการแนะนําอัลกอริทึมและรูปแบบเพิ่มเติม ส่วนหัวนี้จะเปลี่ยนแปลงไปตามนั้น คุณจะระบุรหัสคีย์หรือไม่ก็ได้ และหากมีการระบุรหัสไม่ถูกต้อง GCP จะลองใช้คีย์ทั้งหมดที่เชื่อมโยงกับบัญชีบริการเพื่อยืนยันโทเค็นและปฏิเสธโทเค็นหากไม่พบคีย์ที่ถูกต้อง Google ขอสงวนสิทธิ์ในการปฏิเสธโทเค็นที่มีรหัสคีย์ไม่ถูกต้องในอนาคต

บัญชีบริการจะใช้อัลกอริทึม RSA SHA-256 และรูปแบบโทเค็น JWT ผลที่ได้คือการนําเสนอ JSON เป็นส่วนหัวดังนี้

{"alg":"RS256","typ":"JWT", "kid":"370ab79b4513eb9bad7c9bd16a95cb76b5b2a56a"}

การนําเสนอ Base64url ของรายการนี้คือ:

          eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsICJraWQiOiIzNzBhYjc5YjQ1MTNlYjliYWQ3YzliZDE2YTk1Y2I3NmI1YjJhNTZhIn0=
การสร้างชุดการอ้างสิทธิ์ JWT

ชุดการอ้างสิทธิ์ JWT มีข้อมูลเกี่ยวกับ JWT รวมถึงสิทธิ์ที่ขอ (ขอบเขต) เป้าหมายของโทเค็น ผู้ออกใบรับรอง เวลาที่ออกโทเค็น และอายุการใช้งานของโทเค็น ช่องส่วนใหญ่เป็นช่องบังคับ ส่วนหัวการอ้างสิทธิ์ JWT เป็นออบเจ็กต์ JSON และใช้ในการคํานวณการคํานวณลายเซ็น เช่นเดียวกับส่วนหัว JWT

การอ้างสิทธิ์ที่จําเป็น

การอ้างสิทธิ์ที่จําเป็นในชุดการอ้างสิทธิ์ JWT แสดงอยู่ด้านล่าง ซึ่งอาจแสดงในลําดับใดก็ได้ในชุดการอ้างสิทธิ์

ชื่อ คำอธิบาย
iss อีเมลของบัญชีบริการ
scope รายการสิทธิ์ที่แอปพลิเคชันขอคั่นด้วยการเว้นวรรค
aud ตัวอธิบายเป้าหมายของการยืนยันเป้าหมาย เมื่อส่งคําขอโทเค็นเพื่อการเข้าถึง ค่านี้จะเป็น https://oauth2.googleapis.com/token เสมอ
exp เวลาหมดอายุของการยืนยัน โดยระบุเป็นวินาทีตั้งแต่ 00:00:00 UTC วันที่ 1 มกราคม 1970 ค่านี้ต้องไม่เกิน 1 ชั่วโมงหลังจากเวลาที่ออก
iat เวลาที่ออกการยืนยัน โดยระบุเป็นวินาทีตั้งแต่ 00:00:00 UTC วันที่ 1 มกราคม 1970

การแสดง JSON ของช่องที่ต้องกรอกในชุดการอ้างสิทธิ์ JWT แสดงอยู่ด้านล่าง

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "scope": "https://www.googleapis.com/auth/devstorage.read_only",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
การอ้างสิทธิ์เพิ่มเติม

ในบางกรณี แอปพลิเคชันสามารถใช้การมอบสิทธิ์ทั่วทั้งโดเมนเพื่อดําเนินการในนาม ผู้ใช้ที่ระบุในองค์กร คุณต้องมีสิทธิ์ในการแอบอ้างบุคคลอื่นประเภทนี้ก่อนที่แอปพลิเคชันจะแอบอ้างเป็นผู้ใช้ได้และโดยปกติแล้วจะมีผู้ดูแลระบบขั้นสูงเป็นผู้จัดการ โปรดดูข้อมูลเพิ่มเติมที่หัวข้อควบคุมการเข้าถึง API ด้วยการมอบสิทธิ์ทั่วทั้งโดเมน

หากต้องการได้รับโทเค็นเพื่อการเข้าถึงที่มอบสิทธิ์เข้าถึงแอปพลิเคชันให้กับทรัพยากร ให้รวมอีเมลของผู้ใช้ในการอ้างสิทธิ์ JWT ที่ตั้งค่าเป็นช่อง sub

ชื่อ คำอธิบาย
sub อีเมลของผู้ใช้ที่แอปพลิเคชันกําลังขอการเข้าถึงที่ได้รับมอบสิทธิ์

หากแอปพลิเคชันไม่มีสิทธิ์แอบอ้างเป็นผู้ใช้ การตอบกลับคําขอโทเค็นเพื่อการเข้าถึงที่มีช่อง sub จะเป็นข้อผิดพลาด

ตัวอย่างชุดการอ้างสิทธิ์ JWT ที่มีช่อง sub แสดงอยู่ด้านล่าง

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "sub": "some.user@example.com",
  "scope": "https://www.googleapis.com/auth/prediction",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
การเข้ารหัสชุดการอ้างสิทธิ์ JWT

ส่วนหัวการอ้างสิทธิ์ JWT ควรมีการเรียงแบบ UTF-8 และเข้ารหัสแบบ Safe64url เหมือนกับส่วนหัว JWT ด้านล่างเป็นตัวอย่างของ JSON ของชุดการอ้างสิทธิ์ JWT

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "scope": "https://www.googleapis.com/auth/prediction",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
การคํานวณลายเซ็น

JSON Web Signature (JWS) คือข้อกําหนดเฉพาะที่ช่วยแนะนํากลไกในการสร้างลายเซ็นสําหรับ JWT อินพุตสําหรับลายเซ็นคืออาร์เรย์ไบต์ของเนื้อหาต่อไปนี้

{Base64url encoded header}.{Base64url encoded claim set}

ต้องใช้อัลกอริทึมการลงนามในส่วนหัว JWT เมื่อประมวลผลลายเซ็น อัลกอริทึมการให้สิทธิ์เดียวที่เซิร์ฟเวอร์การให้สิทธิ์ของ Google OAuth 2.0 รองรับคือ RSA โดยใช้อัลกอริทึมการแฮช SHA-256 ซึ่งจะแสดงเป็น RS256 ในช่อง alg ในส่วนหัว JWT

ลงนามการแสดงแทน UTF-8 ของอินพุตโดยใช้ SHA256withRSA (หรือที่เรียกว่า RSASSA-PKCS1-V1_5-SIGN ด้วยฟังก์ชันแฮช SHA-256) ด้วยคีย์ส่วนตัวที่ได้รับจาก Google API Consoleผลลัพธ์จะเป็นอาร์เรย์ไบต์

จากนั้นลายเซ็นจะต้องเข้ารหัสแบบ Base64url ส่วนหัว ชุดการอ้างสิทธิ์ และลายเซ็นจะเชื่อมติดกันด้วยอักขระจุด (.) ผลลัพธ์คือ JWT ซึ่งควรเป็นค่าต่อไปนี้ (เพิ่มตัวแบ่งบรรทัดเพื่อความชัดเจน)

{Base64url encoded header}.
{Base64url encoded claim set}.
{Base64url encoded signature}

ด้านล่างนี้เป็นตัวอย่างของ JWT ก่อนการเข้ารหัส Base64url

{"alg":"RS256","typ":"JWT"}.
{
"iss":"761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
"scope":"https://www.googleapis.com/auth/prediction",
"aud":"https://oauth2.googleapis.com/token",
"exp":1328554385,
"iat":1328550785
}.
[signature bytes]

ด้านล่างนี้เป็นตัวอย่างของ JWT ที่มีการลงชื่อและพร้อมสําหรับการส่ง

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL29hdXRoMi92NC90b2tlbiIsImV4cCI6MTMyODU1NDM4NSwiaWF0IjoxMzI4NTUwNzg1fQ.UFUt59SUM2_AW4cRU8Y0BYVQsNTo4n7AFsNrqOpYiICDu37vVt-tw38UKzjmUKtcRsLLjrR3gFW3dNDMx_pL9DVjgVHDdYirtrCekUHOYoa1CMR66nxep5q5cBQ4y4u2kIgSvChCTc9pmLLNoIem-ruCecAJYgI9Ks7pTnW1gkOKs0x3YpiLpzplVHAkkHztaXiJdtpBcY1OXyo6jTQCa3Lk2Q3va1dPkh_d--GU2M5flgd8xNBPYw4vxyt0mP59XZlHMpztZt0soSgObf7G3GXArreF_6tpbFsS3z2t5zkEiHuWJXpzcYr5zWTRPDEHsejeBSG8EgpLDce2380ROQ

การส่งคําขอโทเค็นเพื่อการเข้าถึง

หลังจากสร้าง JWT ที่ลงชื่อแล้ว แอปพลิเคชันจะสามารถใช้โทเค็นดังกล่าวเพื่อขอโทเค็นเพื่อการเข้าถึงได้ คําขอโทเค็นเพื่อการเข้าถึงนี้เป็นคําขอ HTTPS POST และส่วนเนื้อหามีการเข้ารหัส URL URL จะแสดงด้านล่างนี้

https://oauth2.googleapis.com/token

ต้องมีพารามิเตอร์ต่อไปนี้ในคําขอ HTTPS POST

ชื่อ คำอธิบาย
grant_type ใช้สตริงต่อไปนี้ โดยเข้ารหัส URL ตามความจําเป็น urn:ietf:params:oauth:grant-type:jwt-bearer
assertion JWT รวมถึงลายเซ็น

ด้านล่างนี้คือดัมพ์ดิบของคําขอ HTTPS POST ที่ใช้ในคําขอโทเค็นเพื่อการเข้าถึง

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.ixOUGehweEVX_UKXv5BbbwVEdcz6AYS-6uQV6fGorGKrHf3LIJnyREw9evE-gs2bmMaQI5_UbabvI4k-mQE4kBqtmSpTzxYBL1TCd7Kv5nTZoUC1CmwmWCFqT9RE6D7XSgPUh_jF1qskLa2w0rxMSjwruNKbysgRNctZPln7cqQ

ด้านล่างเป็นคําขอเดียวกัน โดยใช้ curl:

curl -d 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.RZVpzWygMLuL-n3GwjW1_yhQhrqDacyvaXkuf8HcJl8EtXYjGjMaW5oiM5cgAaIorrqgYlp4DPF_GuncFqg9uDZrx7pMmCZ_yHfxhSCXru3gbXrZvAIicNQZMFxrEEn4REVuq7DjkTMyCMGCY1dpMa8aWfTQFt3Eh7smLchaZsU
' https://oauth2.googleapis.com/token

การจัดการการตอบกลับ

หากคําขอ JWT และโทเค็นเพื่อการเข้าถึงมีรูปแบบเหมาะสม และบัญชีบริการมีสิทธิ์ดําเนินการ การตอบกลับ JSON จากเซิร์ฟเวอร์การให้สิทธิ์จะมีโทเค็นเพื่อการเข้าถึง ตัวอย่างคําตอบมีดังนี้

{
  "access_token": "1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M",
  "scope": "https://www.googleapis.com/auth/prediction"
  "token_type": "Bearer",
  "expires_in": 3600
}

คุณใช้โทเค็นเพื่อการเข้าถึงซ้ําได้ในช่วงกรอบเวลาที่ระบุโดยค่า expires_in

การเรียกใช้ API ของ Google

Java

ใช้ออบเจ็กต์ GoogleCredential เพื่อเรียกใช้ Google APIs โดยทําตามขั้นตอนต่อไปนี้

  1. สร้างออบเจ็กต์บริการสําหรับ API ที่คุณต้องการเรียกใช้โดยใช้ออบเจ็กต์ GoogleCredential ตัวอย่างเช่น
    SQLAdmin sqladmin =
        new SQLAdmin.Builder(httpTransport, JSON_FACTORY, credential).build();
  2. ส่งคําขอไปยังบริการ API โดยใช้อินเทอร์เฟซที่ออบเจ็กต์บริการมีให้ ตัวอย่างเช่น หากต้องการแสดงอินสแตนซ์ของฐานข้อมูล Cloud SQL ในโปรเจ็กต์ที่น่าตื่นเต้น example-123
    SQLAdmin.Instances.List instances =
        sqladmin.instances().list("exciting-example-123").execute();

Python

ใช้ออบเจ็กต์ Credentials ที่ได้รับอนุญาตเพื่อเรียก Google APIs โดยทําตามขั้นตอนต่อไปนี้

  1. สร้างออบเจ็กต์บริการสําหรับ API ที่คุณต้องการเรียกใช้ คุณสร้างออบเจ็กต์บริการโดยเรียกฟังก์ชัน build ด้วยชื่อและเวอร์ชันของ API และออบเจ็กต์ Credentials ที่ได้รับอนุญาต เช่น หากต้องการเรียกเวอร์ชัน 1 เบต้า 3 ของ Cloud SQL Administration API
    import googleapiclient.discovery
    
    sqladmin = googleapiclient.discovery.build('sqladmin', 'v1beta3', credentials=credentials)
  2. ส่งคําขอไปยังบริการ API โดยใช้อินเทอร์เฟซที่ออบเจ็กต์บริการมีให้ ตัวอย่างเช่น หากต้องการแสดงอินสแตนซ์ของฐานข้อมูล Cloud SQL ในโปรเจ็กต์ที่น่าตื่นเต้น example-123
    response = sqladmin.instances().list(project='exciting-example-123').execute()

HTTP/REST

หลังจากที่แอปพลิเคชันได้รับโทเค็นเพื่อการเข้าถึง คุณจะใช้โทเค็นนั้นเพื่อเรียก API ของ Google ในนามของบัญชีบริการหรือบัญชีผู้ใช้หนึ่งๆ ได้ หากได้ให้สิทธิ์ขอบเขตที่ API ต้องการแล้ว โดยใส่โทเค็นเพื่อการเข้าถึงในคําขอของ API โดยรวมพารามิเตอร์การค้นหา access_token หรือค่า Authorization ของส่วนหัว HTTP ไว้ใน Bearer หากเป็นไปได้ ส่วนหัว HTTP จะเป็นที่ต้องการมากกว่า เนื่องจากสตริงการค้นหามักจะมองเห็นได้ในบันทึกของเซิร์ฟเวอร์ ในกรณีส่วนใหญ่ คุณสามารถใช้ไลบรารีของไคลเอ็นต์เพื่อตั้งค่าการเรียกไปยัง Google API (เช่น เมื่อเรียกใช้ Drive Files API)

คุณจะลองใช้ Google API ทั้งหมดและดูขอบเขตได้ที่ OAuth 2.0 Playground

ตัวอย่าง HTTP GET

การเรียกปลายทาง drive.files (Drive Files API) โดยใช้ส่วนหัว HTTP ของ Authorization: Bearer อาจมีลักษณะดังนี้ โปรดทราบว่าคุณต้องระบุโทเค็นเพื่อการเข้าถึงของคุณเอง ดังนี้

GET /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

ต่อไปนี้เป็นการเรียกไปยัง API เดียวกันสําหรับผู้ใช้ที่ตรวจสอบสิทธิ์แล้วโดยใช้พารามิเตอร์สตริงคําค้นหา access_token ดังนี้

GET https://www.googleapis.com/drive/v2/files?access_token=access_token

ตัวอย่างของ curl

คุณทดสอบคําสั่งเหล่านี้ได้โดยใช้แอปพลิเคชันบรรทัดคําสั่ง curl ตัวอย่างที่ใช้ตัวเลือกส่วนหัว HTTP (แนะนํา)

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files

หรืออีกทางเลือกหนึ่งคือ พารามิเตอร์สตริงคําค้นหา

curl https://www.googleapis.com/drive/v2/files?access_token=access_token

เมื่อโทเค็นเพื่อการเข้าถึงหมดอายุ

โทเค็นเพื่อการเข้าถึงที่ออกโดยเซิร์ฟเวอร์การให้สิทธิ์ Google OAuth 2.0 จะหมดอายุหลังจากระยะเวลาที่ระบุโดยค่า expires_in เมื่อโทเค็นเพื่อการเข้าถึงหมดอายุ แอปพลิเคชันควรสร้าง JWT อื่น ลงชื่อโทเค็น และขอโทเค็นเพื่อการเข้าถึงอื่น

รหัสข้อผิดพลาดของ JWT

ช่อง error ช่อง error_description ความหมาย วิธีแก้ไข
unauthorized_client Unauthorized client or scope in request. หากพยายามใช้การมอบสิทธิ์ทั่วทั้งโดเมน บัญชีบริการนั้นจะไม่ได้รับอนุญาตในคอนโซลผู้ดูแลระบบของโดเมนของผู้ใช้

ตรวจสอบว่าบัญชีบริการได้รับอนุญาตในหน้า การมอบสิทธิ์ทั่วทั้งโดเมนของคอนโซลผู้ดูแลระบบสําหรับผู้ใช้ในการอ้างสิทธิ์ (ช่อง) sub

แม้ว่าโดยปกติจะใช้เวลา 2-3 นาที แต่การอนุมัติอาจใช้เวลาถึง 24 ชั่วโมงจึงจะมีผลกับผู้ใช้ทุกคนในบัญชี Google ของคุณ

unauthorized_client Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested. บัญชีบริการได้รับอนุญาตโดยใช้อีเมลไคลเอ็นต์ แทนที่จะเป็นรหัสไคลเอ็นต์ (ตัวเลข) ในคอนโซลผู้ดูแลระบบ ในหน้า การมอบสิทธิ์ทั่วทั้งโดเมนในคอนโซลผู้ดูแลระบบ ให้นําไคลเอ็นต์ออกแล้วเพิ่มกลับเข้าไปใหม่ด้วยรหัสตัวเลข
access_denied (ค่าใดก็ได้) หากคุณใช้การมอบสิทธิ์ทั่วทั้งโดเมน ระบบจะไม่ให้สิทธิ์ขอบเขตที่ขออย่างน้อย 1 รายการในคอนโซลผู้ดูแลระบบ

ตรวจสอบว่าบัญชีบริการได้รับอนุญาตในหน้า การมอบสิทธิ์ทั่วทั้งโดเมนของคอนโซลผู้ดูแลระบบสําหรับผู้ใช้ในการอ้างสิทธิ์ (ช่อง) sub (ช่อง) และรวมขอบเขตทั้งหมดที่คุณขอในการอ้างสิทธิ์ scope ของ JWT

แม้ว่าโดยปกติจะใช้เวลา 2-3 นาที แต่การอนุมัติอาจใช้เวลาถึง 24 ชั่วโมงจึงจะมีผลกับผู้ใช้ทุกคนในบัญชี Google ของคุณ

admin_policy_enforced (ค่าใดก็ได้) บัญชี Google ให้สิทธิ์ขอบเขตที่ขออย่างน้อย 1 รายการไม่ได้เนื่องจากนโยบายของผู้ดูแลระบบ Google Workspace

อ่านบทความความช่วยเหลือสําหรับผู้ดูแลระบบ Google Workspace เพื่อควบคุมว่าจะให้แอปของบุคคลที่สามและแอปภายในรายการใดเข้าถึงข้อมูล Google Workspace ได้บ้าง เพื่อดูข้อมูลเพิ่มเติมเกี่ยวกับวิธีที่ผู้ดูแลระบบอาจจํากัดการเข้าถึงขอบเขตทั้งหมดหรือขอบเขตที่จํากัดและละเอียดอ่อนจนกว่าสิทธิ์เข้าถึงรหัสไคลเอ็นต์ OAuth จะมีความชัดเจน

invalid_client (ค่าใดก็ได้)

ไคลเอ็นต์ OAuth หรือโทเค็น JWT ไม่ถูกต้องหรือกําหนดค่าไม่ถูกต้อง

โปรดดูรายละเอียดในคําอธิบายข้อผิดพลาด

ตรวจสอบว่าโทเค็น JWT ถูกต้องและมีการอ้างสิทธิ์ที่ถูกต้อง

ตรวจสอบว่าไคลเอ็นต์ OAuth และบัญชีบริการมีการกําหนดค่าอย่างถูกต้อง และคุณใช้ที่อยู่อีเมลที่ถูกต้อง

ตรวจสอบว่าโทเค็น JWT ถูกต้องและออกให้สําหรับไคลเอ็นต์ในคําขอ

invalid_grant Not a valid email. ไม่มีผู้ใช้นี้ ตรวจสอบว่าอีเมลในการอ้างสิทธิ์ (ช่อง) ของ sub ถูกต้อง
invalid_grant

Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your 'iat' and 'exp' values and use a clock with skew to account for clock differences between systems.

โดยทั่วไปแล้วหมายความว่าเวลาระบบท้องถิ่นไม่ถูกต้อง กรณีนี้อาจเกิดขึ้นได้หากค่า exp ยาวกว่า 65 นาทีในอนาคตจากค่า iat หรือค่า exp ต่ํากว่า iat

ตรวจสอบว่านาฬิกาของระบบที่สร้าง JWT ถูกต้อง หากจําเป็น ให้ซิงค์เวลากับ Google NTP

invalid_grant Invalid JWT Signature.

การยืนยัน JWT มีการลงนามกับคีย์ส่วนตัวที่ไม่ได้เชื่อมโยงกับบัญชีบริการที่ระบุโดยอีเมลของลูกค้า หรือคีย์ที่ใช้ถูกลบ ปิดใช้งาน หรือหมดอายุแล้ว

ไม่เช่นนั้น การยืนยันความถูกต้องของ JWT อาจเข้ารหัสไม่ถูกต้อง โดยต้องเข้ารหัสแบบ Base64 โดยไม่มีบรรทัดใหม่หรือระยะห่างจากขอบเท่ากัน

ถอดรหัสชุดการอ้างสิทธิ์ JWT และยืนยันคีย์ที่ลงนามการยืนยันจะเชื่อมโยงกับบัญชีบริการ

ลองใช้ไลบรารี OAuth จาก Google เพื่อให้แน่ใจว่าระบบสร้าง JWT ได้อย่างถูกต้อง

invalid_scope Invalid OAuth scope or ID token audience provided. ไม่มีการขอขอบเขตใดๆ (รายการขอบเขตว่างเปล่า) หรือหนึ่งในขอบเขตที่ขอไม่มีอยู่ (นั่นคือ ไม่ถูกต้อง)

ตรวจสอบว่าระบบอ้างสิทธิ์ scope (ช่อง) ของ JWT และเปรียบเทียบขอบเขตที่อยู่ในขอบเขตที่กําหนดขอบเขตสําหรับ API ที่ต้องการใช้ เพื่อให้มั่นใจว่าไม่มีข้อผิดพลาดหรือการพิมพ์ผิด

โปรดทราบว่ารายการขอบเขตในการอ้างสิทธิ์ scope จะต้องคั่นด้วยการเว้นวรรค ไม่ใช่เครื่องหมายจุลภาค

disabled_client The OAuth client was disabled. คีย์ที่ใช้ในการลงนามการยืนยัน JWT ปิดใช้อยู่

ไปที่ Google API Consoleจากนั้นในส่วน IAM & Admin > บัญชีบริการ ให้เปิดใช้บัญชีบริการซึ่งมี "รหัสคีย์" ที่ใช้เพื่อรับรองการยืนยัน

org_internal This client is restricted to users within its organization. รหัสไคลเอ็นต์ OAuth ในคําขอเป็นส่วนหนึ่งของโปรเจ็กต์ที่จํากัดการเข้าถึงบัญชี Google ใน องค์กร Google Cloud ที่ระบุ

ใช้บัญชีบริการจากองค์กรเพื่อตรวจสอบสิทธิ์ ยืนยันการกําหนดค่าประเภทผู้ใช้สําหรับแอปพลิเคชัน OAuth

ข้อมูลเพิ่มเติม: การให้สิทธิ์บัญชีบริการโดยไม่มี OAuth

เมื่อใช้ Google API บางรายการ คุณจะเรียก API ที่ได้รับอนุญาตได้โดยใช้ JWT ที่ลงชื่อแล้วเป็นโทเค็นสําหรับผู้ถือโดยตรง แทนการใช้โทเค็นการเข้าถึง OAuth 2.0 หากเป็นไปได้ ให้หลีกเลี่ยงการส่งคําขอเครือข่ายไปยังเซิร์ฟเวอร์การให้สิทธิ์ของ Google ก่อนที่จะเรียก API

หาก API ที่คุณต้องการเรียกใช้มีคําจํากัดความของบริการที่เผยแพร่ในที่เก็บ Google APIs GitHub คุณจะเรียกใช้ API ที่ได้รับอนุญาตได้โดยใช้ JWT แทนโทเค็นเพื่อการเข้าถึง โดยทำตามวิธีต่อไปนี้

  1. สร้างบัญชีบริการตามที่อธิบายข้างต้น โปรดเก็บไฟล์ JSON ที่คุณได้รับเมื่อสร้างบัญชี
  2. ใช้ไลบรารี JWT มาตรฐาน เช่น ไลบรารี jwt.io เพื่อสร้าง JWT ด้วยส่วนหัวและเพย์โหลด ดังตัวอย่างต่อไปนี้
    {
      "alg": "RS256",
      "typ": "JWT",
      "kid": "abcdef1234567890"
    }
    .
    {
      "iss": "123456-compute@developer.gserviceaccount.com",
      "sub": "123456-compute@developer.gserviceaccount.com",
      "aud": "https://firestore.googleapis.com/",
      "iat": 1511900000,
      "exp": 1511903600
    }
    • สําหรับช่อง kid ในส่วนหัว ให้ระบุรหัสคีย์ส่วนตัวของบัญชีบริการ โดยค่าจะอยู่ในช่อง private_key_id ของไฟล์ JSON ของบัญชีบริการ
    • สําหรับช่อง iss และ sub ให้ระบุอีเมลของบัญชีบริการ คุณดูค่านี้ได้ในช่อง client_email ของไฟล์ JSON ของบัญชีบริการ
    • สําหรับช่อง aud ให้ระบุปลายทางของ API เช่น https://SERVICE.googleapis.com/
    • สําหรับช่อง iat ให้ระบุเวลา Unix ปัจจุบันและระบุเวลาที่แน่นอนในอีก 3,600 วินาทีสําหรับช่อง exp เพื่อระบุเวลาที่ JWT จะหมดอายุ

ลงนามใน JWT ด้วย RSA-256 โดยใช้คีย์ส่วนตัวที่พบในไฟล์ JSON ของบัญชีบริการ

เช่น

Java

ใช้ google-api-java-client และ java-jwt ดังนี้

GoogleCredential credential =
        GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"));
PrivateKey privateKey = credential.getServiceAccountPrivateKey();
String privateKeyId = credential.getServiceAccountPrivateKeyId();

long now = System.currentTimeMillis();

try {
    Algorithm algorithm = Algorithm.RSA256(null, privateKey);
    String signedJwt = JWT.create()
        .withKeyId(privateKeyId)
        .withIssuer("123456-compute@developer.gserviceaccount.com")
        .withSubject("123456-compute@developer.gserviceaccount.com")
        .withAudience("https://firestore.googleapis.com/")
        .withIssuedAt(new Date(now))
        .withExpiresAt(new Date(now + 3600 * 1000L))
        .sign(algorithm);
} catch ...

Python

การใช้ PyJWT

iat = time.time()
exp = iat + 3600
payload = {'iss': '123456-compute@developer.gserviceaccount.com',
           'sub': '123456-compute@developer.gserviceaccount.com',
           'aud': 'https://firestore.googleapis.com/',
           'iat': iat,
           'exp': exp}
additional_headers = {'kid': PRIVATE_KEY_ID_FROM_JSON}
signed_jwt = jwt.encode(payload, PRIVATE_KEY_FROM_JSON, headers=additional_headers,
                       algorithm='RS256')
  1. เรียก API โดยใช้ JWT ที่ลงชื่อแล้วเป็นโทเค็นสําหรับผู้ถือ:
    GET /v1/projects/abc/databases/123/indexes HTTP/1.1
    Authorization: Bearer SIGNED_JWT
    Host: firestore.googleapis.com