วิธีจัดการสิทธิ์แบบละเอียด

ภาพรวม

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

สิทธิ์แบบละเอียดคืออะไร

สมมติว่าคุณพัฒนาแอปเพื่อการทำงานที่ขอทั้งขอบเขตอีเมลและปฏิทิน ผู้ใช้ อาจต้องการใช้แอปพลิเคชันของคุณกับ Google ปฏิทินเท่านั้น แต่ไม่ต้องการใช้กับ Gmail สิทธิ์ OAuth แบบละเอียดช่วยให้ผู้ใช้เลือกให้สิทธิ์ Google ปฏิทินเท่านั้นได้ แต่ไม่ให้สิทธิ์ Gmail การอนุญาตให้ผู้ใช้ให้สิทธิ์เข้าถึงข้อมูลที่เฉพาะเจาะจงจะช่วยลดการเปิดเผยข้อมูล เสริมสร้าง ความไว้วางใจ และช่วยให้ผู้ใช้ควบคุมชีวิตดิจิทัลของตนเองได้โดยคำนึงถึงความเป็นส่วนตัวเป็นอันดับแรก คุณจึงควร ออกแบบแอปพลิเคชันให้รองรับสถานการณ์ดังกล่าว

เมื่อมีการขอขอบเขตที่ไม่ต้องลงชื่อเข้าใช้มากกว่า 1 รายการ

ขอบเขตการลงชื่อเข้าใช้และขอบเขตที่ไม่ต้องลงชื่อเข้าใช้

สำหรับแอปพลิเคชันที่ขอทั้งขอบเขตการลงชื่อเข้าใช้และขอบเขตที่ไม่ต้องลงชื่อเข้าใช้ ผู้ใช้จะเห็นหน้าความยินยอม สำหรับขอบเขตการลงชื่อเข้าใช้ (email, profile และ openid) ก่อน หลังจากที่ผู้ใช้ยินยอมให้ แชร์ข้อมูลระบุตัวตนพื้นฐาน (ชื่อ อีเมล และรูปโปรไฟล์) แล้ว ผู้ใช้จะเห็น หน้าจอความยินยอมให้สิทธิ์แบบละเอียดสำหรับขอบเขตที่ไม่ต้องลงชื่อเข้าใช้ ในกรณีนี้ แอปพลิเคชัน ต้องตรวจสอบว่าผู้ใช้ให้สิทธิ์ขอบเขตใดบ้าง และไม่สามารถถือว่าผู้ใช้ให้สิทธิ์ขอบเขตที่ขอทั้งหมด ในตัวอย่างต่อไปนี้ เว็บแอปพลิเคชันจะขอขอบเขตการลงชื่อเข้าใช้ทั้ง 3 รายการและ ขอบเขตที่ไม่ต้องลงชื่อเข้าใช้ของ Google ไดรฟ์ หลังจากที่ผู้ใช้ยินยอมให้ขอบเขตการลงชื่อเข้าใช้แล้ว ผู้ใช้จะเห็นหน้าจอคำยินยอมสำหรับสิทธิ์แบบละเอียดสำหรับสิทธิ์ของ Google ไดรฟ์ ดังนี้

ขอบเขตการลงชื่อเข้าใช้และขอบเขตที่ไม่ต้องลงชื่อเข้าใช้

ขอบเขตที่ไม่ต้องลงชื่อเข้าใช้มากกว่า 1 รายการ

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

ขอบเขตที่ไม่ต้องลงชื่อเข้าใช้มากกว่า 1 รายการ

สำหรับแอปพลิเคชันที่ขอเฉพาะขอบเขตการลงชื่อเข้าใช้ (email, profile และ openid) หน้าจอขอความยินยอมให้สิทธิ์แบบละเอียด จะไม่มีผล ผู้ใช้จะอนุมัติหรือปฏิเสธคำขอลงชื่อเข้าใช้ทั้งหมด กล่าวอีกนัยหนึ่งคือ หากแอปพลิเคชันขอเฉพาะขอบเขตการลงชื่อเข้าใช้ (1, 2 หรือทั้ง 3 รายการ ) หน้าจอขอความยินยอมให้ใช้สิทธิ์แบบละเอียดจะไม่เกี่ยวข้อง

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

จำนวนขอบเขตการลงชื่อเข้าใช้ จำนวนขอบเขตที่ไม่ต้องลงชื่อเข้าใช้ หน้าจอขอความยินยอมสำหรับสิทธิ์แบบละเอียด
1-3 0 ไม่เกี่ยวข้อง
1-3 1+ เกี่ยวข้อง
0 1 ไม่เกี่ยวข้อง
0 2+ เกี่ยวข้อง

ตรวจสอบว่าแอปพลิเคชันของคุณได้รับผลกระทบหรือไม่

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

วิธีตรวจสอบว่าแอปพลิเคชันของคุณใช้ขอบเขตหลายรายการหรือไม่

ตรวจสอบโค้ดของแอปหรือ การเรียกเครือข่ายขาออกเพื่อดูว่าคำขอการให้สิทธิ์ OAuth 2.0 ของ Google ที่แอปของคุณสร้างขึ้นจะทำให้หน้าจอขอความยินยอมให้ใช้สิทธิ์แบบละเอียด แสดงหรือไม่

ตรวจสอบโค้ดของแอปพลิเคชัน

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

Google Identity Services

ข้อมูลโค้ดไลบรารี JavaScript ของ Google Identity Services ต่อไปนี้จะเริ่มต้น TokenClient ด้วยขอบเขตที่ไม่ใช่การลงชื่อเข้าใช้หลายรายการ หน้าจอขอความยินยอมให้สิทธิ์แบบละเอียดจะแสดงเมื่อเว็บ แอปขอสิทธิ์จากผู้ใช้

const client = google.accounts.oauth2.initTokenClient({
  client_id: 'YOUR_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly \
  https://www.googleapis.com/auth/contacts.readonly',
  callback: (response) => {
    ...
  },
});

Python

ข้อมูลโค้ดต่อไปนี้ใช้โมดูล google-auth-oauthlib.flow เพื่อ สร้างคำขอการให้สิทธิ์ พารามิเตอร์ scope มีขอบเขต 2 รายการ ที่ไม่ต้องลงชื่อเข้าใช้ หน้าจอขอความยินยอมให้สิทธิ์แบบละเอียดจะแสดงเมื่อเว็บ แอปพลิเคชันขอการให้สิทธิ์จากผู้ใช้

import google.oauth2.credentials
import google_auth_oauthlib.flow

# Use the client_secret.json file to identify the application requesting
# authorization. The client ID (from that file) and access scopes are required.
flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file(
    'client_secret.json',
    scopes=['https://www.googleapis.com/auth/calendar.readonly',
                    'https://www.googleapis.com/auth/contacts.readonly'])

Node.js

ข้อมูลโค้ดต่อไปนี้สร้างออบเจ็กต์ google.auth.OAuth2 ซึ่งกำหนดพารามิเตอร์ในคำขอการให้สิทธิ์ที่มีพารามิเตอร์ scope ซึ่งมีขอบเขตที่ไม่ต้องลงชื่อเข้าใช้ 2 รายการ หน้าจอขอความยินยอมให้สิทธิ์แบบละเอียดจะแสดงเมื่อเว็บแอป ขอการให้สิทธิ์จากผู้ใช้

const {google} = require('googleapis');

/**
  * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI
  * from the client_secret.json file. To get these credentials for your application, visit
  * https://console.cloud.google.com/apis/credentials.
  */
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// Access scopes for read-only Calendar and Contacts.
const scopes = [
  'https://www.googleapis.com/auth/calendar.readonly',
  'https://www.googleapis.com/auth/contacts.readonly']
];

// Generate a url that asks permissions
const authorizationUrl = oauth2Client.generateAuthUrl({
  // 'online' (default) or 'offline' (gets refresh_token)
  access_type: 'offline',
  /** Pass in the scopes array defined above.
    * Alternatively, if only one scope is needed, you can pass a scope URL as a string */
  scope: scopes,
  // Enable incremental authorization. Recommended as best practices.
  include_granted_scopes: true
});

ตรวจสอบการเรียกเครือข่ายขาออก

วิธีการตรวจสอบการเรียกเครือข่ายจะแตกต่างกันไปตามประเภทไคลเอ็นต์ของแอปพลิเคชัน

ขณะตรวจสอบการเรียกเครือข่าย ให้มองหาคำขอที่ส่งไปยังปลายทางการให้สิทธิ์ของ Google OAuth และตรวจสอบพารามิเตอร์ scope

ค่าเหล่านี้ทำให้หน้าจอความยินยอมให้ใช้สิทธิ์แบบละเอียดแสดงขึ้น

  • พารามิเตอร์ scope มีขอบเขตการลงชื่อเข้าใช้และขอบเขตที่ไม่ใช่การลงชื่อเข้าใช้

    คำขอตัวอย่างต่อไปนี้มีขอบเขตการลงชื่อเข้าใช้ทั้ง 3 รายการและขอบเขตที่ไม่ใช่การลงชื่อเข้าใช้ 1 รายการ เพื่อดูข้อมูลเมตาของไฟล์ใน Google ไดรฟ์ของผู้ใช้

    https://accounts.google.com/o/oauth2/v2/auth?
    access_type=offline&
    scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.email%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fuserinfo.profile%20openid%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.metadata.readonly&
    include_granted_scopes=true&
    response_type=code&
    redirect_uri=YOUR_REDIRECT_URL&
    client_id=YOUR_CLIENT_ID
  • พารามิเตอร์ scope มีขอบเขตที่ไม่ต้องลงชื่อเข้าใช้มากกว่า 1 รายการ

    คำขอตัวอย่างต่อไปนี้มีขอบเขตที่ไม่ต้องลงชื่อเข้าใช้ 2 รายการเพื่อดูข้อมูลเมตาของ Google ไดรฟ์ของผู้ใช้ และจัดการไฟล์ Google ไดรฟ์ที่เฉพาะเจาะจง

  • https://accounts.google.com/o/oauth2/v2/auth?
    access_type=offline&
    scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.metadata.readonly%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive.file&
    include_granted_scopes=true&
    response_type=code&
    redirect_uri=YOUR_REDIRECT_URL&
    client_id=YOUR_CLIENT_ID

แนวทางปฏิบัติแนะนำในการจัดการสิทธิ์แบบละเอียด

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

  1. อ่าน บริการ Google API: นโยบายข้อมูลผู้ใช้และตรวจสอบว่าคุณปฏิบัติตามนโยบายดังกล่าว
  2. ขอขอบเขตที่เฉพาะเจาะจงซึ่งจำเป็นสำหรับงาน คุณต้องปฏิบัติตามนโยบาย Google OAuth 2.0 โดยขอเฉพาะขอบเขตที่คุณต้องการ คุณควรหลีกเลี่ยงการขอขอบเขตหลายรายการ พร้อมกันเมื่อลงชื่อเข้าใช้ เว้นแต่จะจำเป็นสำหรับฟังก์ชันหลักของแอป การรวม ขอบเขตหลายรายการไว้ด้วยกัน โดยเฉพาะอย่างยิ่งสำหรับผู้ใช้ครั้งแรกที่ไม่คุ้นเคยกับฟีเจอร์ของแอปพลิเคชัน อาจทำให้ผู้ใช้เข้าใจได้ยากว่าทำไมจึงต้องมีสิทธิ์เหล่านี้ ซึ่งอาจทำให้เกิดการแจ้งเตือนและทำให้ผู้ใช้ไม่กล้ามีส่วนร่วมกับแอปพลิเคชันของคุณต่อไป
  3. ให้เหตุผลแก่ผู้ใช้ก่อนที่จะขอคำขอการให้สิทธิ์ อธิบายอย่างชัดเจนว่าทำไมแอปพลิเคชันของคุณจึงต้องได้รับสิทธิ์ที่ขอ สิ่งที่คุณจะทำกับข้อมูลของผู้ใช้ และผู้ใช้จะได้รับประโยชน์อย่างไรจากการอนุมัติคำขอ การวิจัยของเราชี้ให้เห็นว่าคำอธิบายเหล่านี้ช่วยเพิ่มความไว้วางใจและการมีส่วนร่วมของผู้ใช้
  4. ใช้ การให้สิทธิ์แบบเพิ่มทีละรายการ ทุกครั้งที่แอปพลิเคชันขอขอบเขตเพื่อหลีกเลี่ยงการจัดการโทเค็นการเข้าถึงหลายรายการ
  5. ตรวจสอบขอบเขตที่ผู้ใช้ให้สิทธิ์ เมื่อขอขอบเขตหลายรายการพร้อมกัน ผู้ใช้อาจไม่ให้สิทธิ์แก่แอปของคุณในทุกขอบเขตที่ขอ แอปของคุณควรตรวจสอบเสมอว่าผู้ใช้ให้สิทธิ์ขอบเขตใดบ้าง และจัดการการปฏิเสธขอบเขตโดยการปิดใช้ฟีเจอร์ที่เกี่ยวข้อง ปฏิบัติตามนโยบาย OAuth 2.0 ของ Google เกี่ยวกับ การจัดการความยินยอมสำหรับขอบเขตหลายรายการและแจ้งให้ผู้ใช้ให้ความยินยอมอีกครั้งเมื่อผู้ใช้ระบุความตั้งใจที่จะใช้ฟีเจอร์ที่เฉพาะเจาะจงซึ่งต้องใช้ขอบเขตอย่างชัดเจน

อัปเดตแอปพลิเคชันเพื่อจัดการสิทธิ์แบบละเอียด

แอปพลิเคชัน Android

คุณควรอ่านเอกสารประกอบของ SDK ที่ใช้เพื่อโต้ตอบกับ Google OAuth 2.0 และ อัปเดตแอปพลิเคชันเพื่อจัดการสิทธิ์แบบละเอียดตามแนวทางปฏิบัติแนะนำ

หากคุณใช้ SDK auth.api.signin จาก Play Services เพื่อโต้ตอบกับ Google OAuth 2.0 คุณจะใช้ฟังก์ชัน requestPermissions เพื่อขอชุดขอบเขตที่เล็กที่สุดที่จำเป็น และฟังก์ชัน hasPermissions เพื่อตรวจสอบว่าผู้ใช้ให้สิทธิ์ขอบเขตใดบ้างเมื่อ ขอสิทธิ์แบบละเอียด

แอปพลิเคชันส่วนขยาย Chrome

คุณควรใช้ Chrome Identity API เพื่อทำงานกับ Google OAuth 2.0 ตาม แนวทางปฏิบัติแนะนำ

ตัวอย่างต่อไปนี้แสดงวิธีจัดการสิทธิ์แบบละเอียดอย่างถูกต้อง

manifest.json

ไฟล์ Manifest ตัวอย่างประกาศขอบเขตที่ไม่ต้องลงชื่อเข้าใช้ 2 รายการสำหรับแอปพลิเคชันส่วนขยาย Chrome

{
  "name": "Example Chrome extension application",
  ...
  "permissions": [
      "identity"
    ],
  "oauth2" : {
      "client_id": "YOUR_CLIENT_ID",
      "scopes":["https://www.googleapis.com/auth/calendar.readonly",
                "https://www.googleapis.com/auth/contacts.readonly"]
  }
}

แนวทางที่ไม่ถูกต้อง

ทั้งหมดหรือไม่มีเลย

ผู้ใช้คลิกปุ่มเพื่อเริ่มกระบวนการให้สิทธิ์ โค้ด Snippet สันนิษฐานว่า ผู้ใช้จะเห็นหน้าจอขอความยินยอมแบบ "ทั้งหมดหรือไม่มีเลย" สำหรับขอบเขต 2 รายการที่ระบุ ในไฟล์ manifest.json โดยไม่ได้ตรวจสอบว่าผู้ใช้ให้สิทธิ์เข้าถึงขอบเขตใด

oauth.js

...
document.querySelector('button').addEventListener('click', function () {
  chrome.identity.getAuthToken({ interactive: true },
      function (token) {
          if (token === undefined) {
            // User didn't authorize both scopes.
            // Updating the UX and application accordingly
            ...
          } else {
            // User authorized both or one of the scopes.
            // It neglects to check which scopes users granted and assumes users granted all scopes.

            // Calling the APIs, etc.
            ...
          }
      });
});

แนวทางที่ถูกต้อง

ขอบเขตที่เล็กที่สุด

เลือกชุดขอบเขตที่เล็กที่สุดที่จำเป็น

แอปพลิเคชันควรขอเฉพาะชุดขอบเขตที่เล็กที่สุดที่จำเป็น เราขอแนะนำ ให้แอปพลิเคชันของคุณขอขอบเขตทีละรายการเมื่อจำเป็นต้องใช้เพื่อทำงานให้เสร็จ

ในตัวอย่างนี้ เราจะถือว่าขอบเขตทั้ง 2 รายการที่ประกาศไว้ในไฟล์ manifest.json เป็นชุดขอบเขตที่เล็กที่สุดที่จำเป็น oauth.js ไฟล์ใช้ Chrome Identity API เพื่อเริ่มกระบวนการให้สิทธิ์กับ Google คุณควรเลือกใช้เพื่อ เปิดใช้สิทธิ์แบบละเอียด เพื่อให้ผู้ใช้ควบคุมการให้สิทธิ์แก่แอปพลิเคชันของคุณได้มากขึ้น แอปพลิเคชันของคุณควรจัดการการตอบกลับจากผู้ใช้อย่างเหมาะสมโดยการตรวจสอบ ว่าผู้ใช้ให้สิทธิ์ขอบเขตใด

oauth.js

...
document.querySelector('button').addEventListener('click', function () {
  chrome.identity.getAuthToken({ interactive: true, enableGranularPermissions: true },
      function (token, grantedScopes) {
          if (token === undefined) {
            // User didn't authorize any scope.
            // Updating the UX and application accordingly
            ...
          } else {
            // User authorized the request. Now, check which scopes were granted.
            if (grantedScopes.includes('https://www.googleapis.com/auth/calendar.readonly'))
            {
              // User authorized Calendar read permission.
              // Calling the APIs, etc.
              ...
            }
            else
            {
              // User didn't authorize Calendar read permission.
              // Update UX and application accordingly
              ...
            }

            if (grantedScopes.includes('https://www.googleapis.com/auth/contacts.readonly'))
            {
              // User authorized Contacts read permission.
              // Calling the APIs, etc.
              ...
            }
            else
            {
              // User didn't authorize Contacts read permission.
              // Update UX and application accordingly
              ...
            }
          }
      });
});

แอปพลิเคชัน iOS, iPadOS และ macOS

คุณควรอ่านเอกสารประกอบของ SDK ที่ใช้เพื่อโต้ตอบกับ Google OAuth 2.0 และ อัปเดตแอปพลิเคชันเพื่อจัดการสิทธิ์แบบละเอียดตามแนวทางปฏิบัติแนะนำ

หากคุณใช้ไลบรารีการลงชื่อเข้าใช้ด้วย Google สำหรับ iOS และ macOS เพื่อโต้ตอบกับ Google OAuth 2.0 คุณควรอ่านเอกสารประกอบเกี่ยวกับการจัดการสิทธิ์แบบละเอียด

เว็บแอปพลิเคชัน

คุณควรอ่านเอกสารประกอบของ SDK ที่ใช้เพื่อโต้ตอบกับ Google OAuth 2.0 และ อัปเดตแอปพลิเคชันเพื่อจัดการสิทธิ์แบบละเอียดตามแนวทางปฏิบัติแนะนำ

การเข้าถึงฝั่งเซิร์ฟเวอร์ (ออฟไลน์)

โหมดการเข้าถึงฝั่งเซิร์ฟเวอร์ (ออฟไลน์) กําหนดให้คุณต้องทําสิ่งต่อไปนี้
  • ตั้งค่าเซิร์ฟเวอร์และกำหนดปลายทางที่เข้าถึงได้แบบสาธารณะเพื่อรับรหัสการให้สิทธิ์
  • กำหนดค่า URI การเปลี่ยนเส้นทาง ของปลายทางสาธารณะใน Clients page ของคอนโซล Google Cloud

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

แนวทางที่ไม่ถูกต้อง

ทั้งหมดหรือไม่มีเลย

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

main.js

...
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// Access scopes for two non-Sign-In scopes - Google Calendar and Contacts
const scopes = [
  'https://www.googleapis.com/auth/contacts.readonly',
  'https://www.googleapis.com/auth/calendar.readonly'
];

// Generate a url that asks permissions for the Google Calendar and Contacts scopes
const authorizationUrl = oauth2Client.generateAuthUrl({
  // 'online' (default) or 'offline' (gets refresh_token)
  access_type: 'offline',
  // Pass in the scopes array defined above
  scope: scopes,
  // Enable incremental authorization. Recommended as best practices.
  include_granted_scopes: true
});

async function main() {
  const server = http.createServer(async function (req, res) {
    // Example on redirecting user to Google OAuth 2.0 server.
    if (req.url == '/') {
      res.writeHead(301, { "Location": authorizationUrl });
    }
    // Receive the callback from Google OAuth 2.0 server.
    if (req.url.startsWith('/oauth2callback')) {
      // Handle the Google OAuth 2.0 server response
      let q = url.parse(req.url, true).query;

      if (q.error) {
        // User didn't authorize both scopes.
        // Updating the UX and application accordingly
        ...
      } else {
        // User authorized both or one of the scopes.
        // It neglects to check which scopes users granted and assumes users granted all scopes.

        // Get access and refresh tokens (if access_type is offline)
        let { tokens } = await oauth2Client.getToken(q.code);
        // Calling the APIs, etc.
        ...
      }
    }
    res.end();
  }).listen(80);
}
แนวทางที่ถูกต้อง

ขอบเขตที่เล็กที่สุด

เลือกชุดขอบเขตที่เล็กที่สุดที่จำเป็น

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

หากแอปพลิเคชันต้องขอขอบเขตที่ไม่ใช่ Sign-In หลายรายการ คุณควรใช้ การให้สิทธิ์แบบเพิ่มทีละรายการ เสมอเมื่อขอและตรวจสอบว่าผู้ใช้ให้สิทธิ์ขอบเขตใดบ้าง

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

main.js

...
const oauth2Client = new google.auth.OAuth2(
  YOUR_CLIENT_ID,
  YOUR_CLIENT_SECRET,
  YOUR_REDIRECT_URL
);

// Access scopes for two non-Sign-In scopes - Google Calendar and Contacts
const scopes = [
  'https://www.googleapis.com/auth/contacts.readonly',
  'https://www.googleapis.com/auth/calendar.readonly'
];

// Generate a url that asks permissions for the Google Calendar and Contacts scopes
const authorizationUrl = oauth2Client.generateAuthUrl({
  // 'online' (default) or 'offline' (gets refresh_token)
  access_type: 'offline',
  // Pass in the scopes array defined above
  scope: scopes,
  // Enable incremental authorization. Recommended as best practices.
  include_granted_scopes: true,
  // Set to true to enable more granular permissions for Google OAuth 2.0 client IDs created before 2019.
  // No effect for newer Google OAuth 2.0 client IDs, since more granular permissions is always enabled for them.
  enable_granular_consent: true
});

async function main() {
  const server = http.createServer(async function (req, res) {
    // Redirect users to Google OAuth 2.0 server.
    if (req.url == '/') {
      res.writeHead(301, { "Location": authorizationUrl });
    }
    // Receive the callback from Google OAuth 2.0 server.
    if (req.url.startsWith('/oauth2callback')) {
      // Handle the Google OAuth 2.0 server response
      let q = url.parse(req.url, true).query;

      if (q.error) {
        // User didn't authorize both scopes.
        // Updating the UX and application accordingly
        ...
      } else {
        // Get access and refresh tokens (if access_type is offline)
        let { tokens } = await oauth2Client.getToken(q.code);
        oauth2Client.setCredentials(tokens);

        // User authorized the request. Now, check which scopes were granted.
        if (tokens.scope.includes('https://www.googleapis.com/auth/calendar.readonly'))
        {
          // User authorized Calendar read permission.
          // Calling the APIs, etc.
          ...
        }
        else
        {
          // User didn't authorize Calendar read permission.
          // Calling the APIs, etc.
          ...
        }

        // Check which scopes user granted the permission to application
        if (tokens.scope.includes('https://www.googleapis.com/auth/contacts.readonly'))
        {
          // User authorized Contacts read permission.
          // Calling the APIs, etc.
          ...
        }
        else
        {
          // User didn't authorize Contacts read permission.
          // Update UX and application accordingly
          ...
        }
      }
    }
    res.end();
  }).listen(80);
}

โปรดอ่าน คู่มือเว็บแอปฝั่งเซิร์ฟเวอร์เกี่ยวกับวิธีเข้าถึง Google API จากแอปพลิเคชันที่ใช้เซิร์ฟเวอร์

สิทธิ์เข้าถึงฝั่งไคลเอ็นต์เท่านั้น

  • สำหรับแอปพลิเคชันที่ใช้ไลบรารี JavaScript ของ Google Identity Services เพื่อโต้ตอบกับ Google OAuth 2.0 คุณควรอ่านเอกสารประกอบ นี้เกี่ยวกับการจัดการสิทธิ์แบบละเอียด
  • สำหรับแอปพลิเคชันที่ทำการเรียกใช้โดยตรงโดยใช้ JavaScript ไปยังปลายทางการให้สิทธิ์ OAuth 2.0 ของ Google คุณควรอ่านเอกสารประกอบ นี้เกี่ยวกับการจัดการสิทธิ์แบบละเอียด

ทดสอบแอปพลิเคชันที่อัปเดตแล้วในการจัดการสิทธิ์แบบละเอียด

  1. ระบุกรณีทั้งหมดที่ผู้ใช้สามารถตอบกลับคำขอสิทธิ์และลักษณะการทำงานที่คาดไว้จากแอปพลิเคชันของคุณ ตัวอย่างเช่น หากผู้ใช้ให้สิทธิ์เพียง 2 ขอบเขตจาก 3 ขอบเขตที่ขอ แอปพลิเคชันของคุณควรทำงานตามนั้น
  2. ทดสอบแอปพลิเคชันโดยเปิดใช้สิทธิ์แบบละเอียด คุณเปิดใช้สิทธิ์แบบละเอียดได้ 2 วิธี ดังนี้
    1. ตรวจสอบหน้าจอคำยินยอม OAuth 2.0 ของแอปพลิเคชันเพื่อดูว่าได้เปิดใช้สิทธิ์แบบละเอียดสำหรับแอปพลิเคชันแล้วหรือไม่ นอกจากนี้ คุณยังสร้างรหัสไคลเอ็นต์ Google OAuth 2.0 สำหรับเว็บ, Android หรือ iOS ใหม่ได้ ผ่านคอนโซล Google Cloud เพื่อวัตถุประสงค์ในการทดสอบ เนื่องจากระบบจะเปิดใช้สิทธิ์แบบละเอียด สำหรับรหัสไคลเอ็นต์เหล่านี้เสมอ
    2. ตั้งค่าพารามิเตอร์ enable_granular_consent เป็น true เมื่อเรียกใช้ Google OAuth ปลายทางการให้สิทธิ์ SDK บางรายการรองรับพารามิเตอร์นี้อย่างชัดเจน สำหรับพารามิเตอร์อื่นๆ โปรดดูเอกสารประกอบเพื่อดูวิธีเพิ่มพารามิเตอร์นี้และ ค่าด้วยตนเอง หากการติดตั้งใช้งานไม่รองรับการเพิ่มพารามิเตอร์ คุณสามารถสร้างรหัสไคลเอ็นต์ Google OAuth 2.0 ใหม่สำหรับเว็บ Android หรือ iOS ผ่าน Google Cloud Console เพื่อวัตถุประสงค์ในการทดสอบเท่านั้น ตามที่ระบุไว้ในจุดก่อนหน้า
  3. เมื่อทดสอบแอปพลิเคชันที่อัปเดตแล้ว ให้ใช้บัญชี Google ส่วนตัว (@gmail.com) แทน บัญชี Workspace เนื่องจากแอป Workspace Enterprise ที่มี การมอบสิทธิ์ระดับโดเมนหรือทำเครื่องหมายเป็น เชื่อถือได้ จะไม่ได้รับผลกระทบจากการเปลี่ยนแปลงสิทธิ์แบบละเอียดในขณะนี้ ดังนั้น การทดสอบด้วยบัญชี Workspace จากองค์กรของคุณอาจไม่แสดงหน้าจอขอความยินยอมแบบละเอียดใหม่ตามที่ตั้งใจไว้