ภาพรวม
สิทธิ์แบบละเอียดจะทำให้ผู้บริโภคควบคุมข้อมูลบัญชีที่ตนเลือกที่จะแชร์กับแต่ละแอปได้ละเอียดยิ่งขึ้น ซึ่งเป็นประโยชน์ต่อทั้งผู้ใช้และนักพัฒนาแอปโดยให้การควบคุม ความโปร่งใส และความปลอดภัยที่มากขึ้น คู่มือนี้จะช่วยให้คุณเข้าใจการเปลี่ยนแปลงและขั้นตอนที่จำเป็นในการอัปเดตแอปพลิเคชันให้จัดการสิทธิ์แบบละเอียดได้
สิทธิ์แบบละเอียดคืออะไร
สมมติว่าคุณพัฒนาแอปเพื่อการทำงานที่ขอทั้งขอบเขตอีเมลและปฏิทิน ผู้ใช้อาจต้องการใช้แอปพลิเคชันของคุณกับ Google ปฏิทินเท่านั้น แต่ไม่ต้องการใช้ Gmail หากมีสิทธิ์ OAuth แบบละเอียด ผู้ใช้จะเลือกให้สิทธิ์ Google ปฏิทินได้เท่านั้น แต่เลือกให้สิทธิ์ Gmail ไม่ได้ การอนุญาตให้ผู้ใช้ให้สิทธิ์เข้าถึงข้อมูลที่เจาะจงจะช่วยลดการเปิดเผยข้อมูลนี้ เพิ่มความไว้วางใจ และช่วยให้ผู้ใช้ควบคุมชีวิตดิจิทัลของตัวเองเป็นอันดับแรกๆ ได้ คุณจึงควรออกแบบแอปพลิเคชันให้รองรับสถานการณ์เช่นนี้
เมื่อมีการขอขอบเขตการไม่ลงชื่อเข้าใช้มากกว่า 1 ขอบเขต
ขอบเขตการลงชื่อเข้าใช้และไม่ได้ลงชื่อเข้าใช้
สำหรับแอปพลิเคชันที่ขอทั้งขอบเขตการลงชื่อเข้าใช้และไม่ได้ลงชื่อเข้าใช้ ผู้ใช้จะเห็นหน้าคำยินยอมสำหรับขอบเขตการลงชื่อเข้าใช้ (email
, profile
และ openid
) ก่อน หลังจากที่ผู้ใช้ยินยอมที่จะแชร์ข้อมูลประจำตัวพื้นฐาน (ชื่อ อีเมล และรูปโปรไฟล์) ผู้ใช้จะเห็นหน้าจอคำยินยอมโดยละเอียดสำหรับขอบเขตที่ไม่ได้ลงชื่อเข้าใช้ ในกรณีนี้ แอปพลิเคชันต้องตรวจสอบว่าผู้ใช้ให้สิทธิ์ขอบเขตใด และจะคิดเอาเองว่าผู้ใช้ให้สิทธิ์ขอบเขตที่ขอทั้งหมดไม่ได้ ในตัวอย่างต่อไปนี้ เว็บแอปพลิเคชันจะขอขอบเขตการลงชื่อเข้าใช้ทั้ง 3 รายการและขอบเขตการไม่ได้ลงชื่อเข้าใช้ของ Google ไดรฟ์ หลังจากที่ผู้ใช้ยินยอมตามขอบเขตการลงชื่อเข้าใช้ ผู้ใช้จะเห็นหน้าจอขอความยินยอมสำหรับสิทธิ์แบบละเอียดสำหรับสิทธิ์ Google ไดรฟ์ ดังนี้
ขอบเขตที่ไม่ได้ลงชื่อเข้าใช้มีมากกว่า 1 ขอบเขต
หน้าจอขอความยินยอมแบบละเอียดจะแสดงแก่ผู้ใช้เมื่อแอปพลิเคชันส่งคำขอขอบเขตที่ไม่ได้ลงชื่อเข้าใช้มากกว่า 1 ขอบเขต ผู้ใช้สามารถเลือกสิทธิ์ที่ต้องการอนุมัติเพื่อแชร์กับแอปพลิเคชันได้ ตัวอย่างหน้าจอขอความยินยอมแบบละเอียดที่ขอสิทธิ์เข้าถึงข้อความ Gmail ของผู้ใช้และข้อมูล Google ปฏิทินมีดังนี้
สำหรับแอปพลิเคชันที่ขอเฉพาะขอบเขตการลงชื่อเข้าใช้ (email
, profile
และ openid
) หน้าจอขอความยินยอมสำหรับสิทธิ์แบบละเอียดจะใช้ไม่ได้ ผู้ใช้จะอนุมัติหรือปฏิเสธคำขอลงชื่อเข้าใช้ทั้งหมดก็ได้ กล่าวคือ หากแอปพลิเคชันขอเฉพาะขอบเขตการลงชื่อเข้าใช้ (1, 2 หรือทั้ง 3) หน้าจอความยินยอมสำหรับสิทธิ์แบบละเอียดจะใช้ไม่ได้
สำหรับแอปพลิเคชันที่ขอขอบเขตการไม่ลงชื่อเข้าใช้เพียง 1 ขอบเขต หน้าจอขอความยินยอมสำหรับสิทธิ์แบบละเอียดจะไม่เกี่ยวข้อง กล่าวคือ ผู้ใช้จะอนุมัติหรือปฏิเสธคำขอทั้งหมดก็ได้ และไม่มีช่องทำเครื่องหมายในหน้าจอคำยินยอม ตารางต่อไปนี้จะสรุปเมื่อหน้าจอขอความยินยอมสำหรับสิทธิ์แบบละเอียดแสดงขึ้น
จำนวนขอบเขตการลงชื่อเข้าใช้ | จำนวนขอบเขตการไม่ลงชื่อเข้าใช้ | หน้าจอขอความยินยอมโดยละเอียด |
---|---|---|
1-3 | 0 | ไม่เกี่ยวข้อง |
1-3 | 1+ | เกี่ยวข้อง |
0 | 1 | ไม่เกี่ยวข้อง |
0 | 2+ | เกี่ยวข้อง |
ตรวจสอบดูว่าแอปพลิเคชันของคุณได้รับผลกระทบหรือไม่
ดำเนินการตรวจสอบทุกส่วนในแอปพลิเคชันของคุณที่มีการใช้ปลายทางการให้สิทธิ์ Google OAuth 2.0 สำหรับคำขอสิทธิ์ โปรดระวังผู้ที่ขอขอบเขตหลายขอบเขตเมื่อเปิดใช้งานหน้าจอขอความยินยอมสำหรับสิทธิ์แบบละเอียดที่แสดงต่อผู้ใช้ ในกรณีดังกล่าว ให้ตรวจสอบว่าโค้ดสามารถรองรับกรณีที่ผู้ใช้ให้สิทธิ์ขอบเขตบางส่วนเท่านั้น
วิธีตรวจสอบว่าแอปพลิเคชันของคุณใช้ขอบเขตหลายขอบเขตหรือไม่
ตรวจสอบโค้ดของแอปหรือการโทรออกเพื่อดูว่าคำขอการให้สิทธิ์ Google OAuth 2.0 สร้างขึ้นจะทำให้หน้าจอขอความยินยอมสำหรับสิทธิ์แบบละเอียดแสดงขึ้นไหม
ตรวจสอบโค้ดของแอปพลิเคชัน
ตรวจสอบส่วนต่างๆ ของโค้ดแอปพลิเคชันที่คุณใช้เรียกปลายทางการให้สิทธิ์ OAuth ของ Google เพื่อขอสิทธิ์จากผู้ใช้ หากใช้ไลบรารีของไคลเอ็นต์ Google API อย่างใดอย่างหนึ่ง คุณมักจะเห็นขอบเขตคำขอของแอปพลิเคชันในขั้นตอนการเริ่มต้นไคลเอ็นต์ ตัวอย่างบางส่วนจะแสดงอยู่ในส่วนต่อไป โปรดดูเอกสารเกี่ยวกับ SDK ที่แอปพลิเคชันใช้จัดการกับ Google OAuth 2.0 เพื่อดูว่าแอปพลิเคชันของคุณได้รับผลกระทบหรือไม่ โดยใช้คำแนะนำที่แสดงในตัวอย่างต่อไปนี้เป็นข้อมูลอ้างอิง
บริการ Google Identity
ข้อมูลโค้ดไลบรารี 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 });
ตรวจสอบสายที่โทรออกผ่านเครือข่าย
- เว็บแอปพลิเคชัน - ตรวจสอบกิจกรรมในเครือข่ายใน Chrome
- Android - ตรวจสอบการจราจรของข้อมูลในเครือข่ายด้วยเครื่องมือตรวจสอบเครือข่าย
-
แอป Chrome
- ไปที่หน้าส่วนขยาย Chrome
- เลือกช่องทำเครื่องหมายโหมดนักพัฒนาซอฟต์แวร์ที่มุมขวาบนของหน้าส่วนขยาย
- เลือกส่วนขยายที่คุณต้องการตรวจสอบ
- คลิกลิงก์หน้าพื้นหลังในส่วนตรวจสอบมุมมองของหน้าส่วนขยาย
- ป๊อปอัปเครื่องมือสำหรับนักพัฒนาซอฟต์แวร์จะปรากฏขึ้นเพื่อให้คุณตรวจสอบการจราจรของข้อมูลในเครือข่ายได้ใน แท็บเครือข่าย
- iOS - การวิเคราะห์การเข้าชม HTTP ด้วยเครื่องมือ
- Universal Windows Platform (UWP) - ตรวจสอบการจราจรของข้อมูลในเครือข่ายใน Visual Studio
- แอปบนเดสก์ท็อป - ใช้เครื่องมือบันทึกเครือข่าย ที่พร้อมใช้งานสำหรับระบบปฏิบัติการที่แอปพัฒนาขึ้น
ขณะตรวจสอบการเรียกเครือข่าย ให้มองหาคำขอที่ส่งไปยังปลายทางการให้สิทธิ์ของ OAuth ของ Google และตรวจสอบพารามิเตอร์ scope
ค่าเหล่านี้causeหน้าจอขอความยินยอมสำหรับสิทธิ์แบบละเอียด
พารามิเตอร์
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
แนวทางปฏิบัติแนะนำในการจัดการกับสิทธิ์แบบละเอียด
หากคุณdetermineว่าจำเป็นต้องอัปเดตแอปพลิเคชันเพื่อจัดการสิทธิ์แบบละเอียด คุณควรอัปเดตโค้ดที่จำเป็นเพื่อจัดการความยินยอมสำหรับขอบเขตหลายขอบเขตอย่างเหมาะสม แอปพลิเคชันทั้งหมดควรปฏิบัติตามแนวทางปฏิบัติแนะนำต่อไปนี้
- อ่าน บริการ Google API: นโยบายข้อมูลผู้ใช้และตรวจสอบว่าคุณปฏิบัติตามนโยบายดังกล่าว
- ส่งคำขอขอบเขตเฉพาะที่จำเป็นสำหรับงาน คุณต้องปฏิบัติตามนโยบาย Google OAuth 2.0 ที่คุณขอเฉพาะขอบเขตที่จำเป็น คุณควรหลีกเลี่ยงการขอขอบเขตหลายขอบเขตเมื่อลงชื่อเข้าใช้ เว้นแต่ว่าจะจำเป็นต่อฟังก์ชันหลักของแอป การรวมขอบเขตหลายขอบเขตเข้าด้วยกัน โดยเฉพาะสำหรับผู้ใช้ครั้งแรกที่ไม่คุ้นเคยกับฟีเจอร์ของแอปพลิเคชัน อาจทำให้ผู้ใช้เข้าใจความจำเป็นของสิทธิ์เหล่านี้ได้ยาก ซึ่งอาจสร้างสัญญาณเตือนและป้องกันไม่ให้ผู้ใช้มีส่วนร่วมกับแอปพลิเคชันของคุณอีก
- ระบุเหตุผลรองรับให้ผู้ใช้ทราบก่อนที่จะส่งคำขอการให้สิทธิ์ อธิบายให้ชัดเจนถึงเหตุผลที่แอปพลิเคชันต้องการสิทธิ์ที่ขอ สิ่งที่คุณจะดำเนินการกับข้อมูลของผู้ใช้ และประโยชน์ที่ผู้ใช้จะได้รับจากการอนุมัติคำขอ การวิจัยของเราแสดงให้เห็นว่าคำอธิบายเหล่านี้ช่วยเพิ่มความไว้วางใจและการมีส่วนร่วมของผู้ใช้
- ใช้ การให้สิทธิ์ที่เพิ่มขึ้นเมื่อใดก็ตามที่แอปพลิเคชันขอขอบเขตเพื่อจะได้ไม่ต้องจัดการโทเค็นเพื่อการเข้าถึงหลายรายการ
- ตรวจสอบขอบเขตที่ผู้ใช้ให้สิทธิ์ เมื่อขอหลายขอบเขตพร้อมกัน ผู้ใช้อาจไม่ให้สิทธิ์ขอบเขตทั้งหมดที่แอปส่งคำขอ แอปควรตรวจสอบทุกครั้งว่าผู้ใช้ให้สิทธิ์ขอบเขตใดและจัดการการปฏิเสธขอบเขตโดยปิดใช้ฟีเจอร์ที่เกี่ยวข้อง ปฏิบัติตามนโยบาย OAuth 2.0 ของ Google เกี่ยวกับการจัดการความยินยอมสำหรับหลายขอบเขต และแจ้งให้ผู้ใช้ขอความยินยอมอีกครั้งเมื่อผู้ใช้ได้ระบุความตั้งใจชัดเจนว่าจะใช้ฟีเจอร์บางอย่างที่ต้องใช้ขอบเขตดังกล่าวเท่านั้น
อัปเดตแอปพลิเคชันเพื่อจัดการสิทธิ์แบบละเอียด
แอปพลิเคชัน Android
คุณควรอ่านเอกสารประกอบของ SDK ที่คุณใช้เพื่อโต้ตอบกับ Google OAuth 2.0 และอัปเดตแอปพลิเคชันให้จัดการสิทธิ์แบบละเอียดตามแนวทางปฏิบัติแนะนำ
หากใช้ SDK ของ auth.api.signin
จากบริการ Google Play เพื่อโต้ตอบกับ 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"] } }
แนวทางที่ไม่ถูกต้อง
ทั้งหมดหรือไม่ใช้เลย
ผู้ใช้จะคลิกปุ่มนี้เพื่อเริ่มกระบวนการให้สิทธิ์ ข้อมูลโค้ดนี้จะถือว่าผู้ใช้เห็นหน้าจอขอความยินยอม "ทั้งหมดหรือไม่ยินยอม" สำหรับขอบเขต 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. ... } }); });
แนวทางที่ถูกต้อง
ขอบเขตที่เล็กที่สุด
เลือกชุดขอบเขตที่เล็กที่สุดเท่าที่จำเป็น
แอปพลิเคชันควรขอเฉพาะขอบเขตที่น้อยที่สุดเท่าที่จำเป็น เราขอแนะนำให้แอปพลิเคชันส่งคำขอไปทีละ 1 ขอบเขตเมื่อจำเป็นต้องทำงานให้เสร็จสิ้น
ในตัวอย่างนี้ ระบบจะถือว่าขอบเขตทั้ง 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 Sign-In สำหรับ iOS และ macOS เพื่อโต้ตอบกับ Google OAuth 2.0 คุณควรอ่านเอกสารประกอบเกี่ยวกับการจัดการสิทธิ์โดยละเอียด
เว็บแอปพลิเคชัน
คุณควรอ่านเอกสารประกอบของ SDK ที่คุณใช้เพื่อโต้ตอบกับ Google OAuth 2.0 และอัปเดตแอปพลิเคชันให้จัดการสิทธิ์แบบละเอียดตามแนวทางปฏิบัติแนะนำ
การเข้าถึงฝั่งเซิร์ฟเวอร์ (ออฟไลน์)
- ยืนเซิร์ฟเวอร์และกำหนดปลายทางที่เข้าถึงได้แบบสาธารณะเพื่อรับรหัสการให้สิทธิ์
- กำหนดค่า URI การเปลี่ยนเส้นทาง ของปลายทางสาธารณะใน Credentials 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); }
แนวทางที่ถูกต้อง
ขอบเขตที่เล็กที่สุด
เลือกชุดขอบเขตที่เล็กที่สุดเท่าที่จำเป็น
แอปพลิเคชันควรขอเฉพาะขอบเขตที่น้อยที่สุดเท่าที่จำเป็น เราขอแนะนำให้แอปพลิเคชันส่งคำขอไปทีละ 1 ขอบเขตเมื่อจำเป็นต้องทำงานให้เสร็จสิ้น เมื่อใดก็ตามที่แอปพลิเคชันของคุณขอขอบเขต แอปพลิเคชันควรใช้การให้สิทธิ์ที่เพิ่มขึ้นเพื่อจะได้ไม่ต้องจัดการโทเค็นเพื่อการเข้าถึงหลายรายการ
หากแอปพลิเคชันต้องขอขอบเขตการไม่ลงชื่อเข้าใช้หลายขอบเขต คุณควรใช้การให้สิทธิ์ที่เพิ่มขึ้นเสมอ เมื่อส่งคำขอและตรวจสอบว่าผู้ใช้ให้สิทธิ์ขอบเขตใดแล้ว
ในตัวอย่างนี้ ระบบสมมติว่าขอบเขตที่ระบุไว้ทั้ง 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 APIs จากแอปพลิเคชันบนเซิร์ฟเวอร์
การเข้าถึงฝั่งไคลเอ็นต์เท่านั้น
- สำหรับแอปพลิเคชันที่ใช้ไลบรารี JavaScript ของ Google Identity Services เพื่อโต้ตอบกับ Google OAuth 2.0 คุณควรอ่านเอกสารประกอบนี้เกี่ยวกับการจัดการสิทธิ์โดยละเอียด
- สำหรับแอปพลิเคชันที่มีการเรียกโดยใช้ JavaScript ไปยังปลายทางการให้สิทธิ์ของ Google OAuth 2.0 โดยตรง คุณควรอ่านเอกสารประกอบนี้เกี่ยวกับการจัดการสิทธิ์แบบละเอียด
ทดสอบแอปพลิเคชันที่อัปเดตแล้วเกี่ยวกับการจัดการสิทธิ์แบบละเอียด
- Outline สำหรับทุกกรณีที่ผู้ใช้ตอบสนองต่อคำขอสิทธิ์และลักษณะการทำงานที่คาดไว้จากแอปพลิเคชันของคุณได้ เช่น หากผู้ใช้ให้สิทธิ์เพียง 2 ใน 3 ขอบเขตที่ขอ แอปพลิเคชันก็ควรจะทำงานตามนั้น
-
ทดสอบแอปพลิเคชันที่เปิดใช้สิทธิ์แบบละเอียด การเปิดใช้สิทธิ์แบบละเอียดมี 2 วิธีดังนี้
- ตรวจสอบหน้าจอความยินยอม OAuth 2.0 ของแอปพลิเคชันเพื่อดูว่าได้เปิดใช้สิทธิ์แบบละเอียดสำหรับแอปพลิเคชันแล้วหรือยัง นอกจากนี้ คุณยังสร้างรหัสไคลเอ็นต์ Google OAuth 2.0 สำหรับเว็บ, Android หรือ iOS ใหม่ผ่านคอนโซล Google Cloud เพื่อวัตถุประสงค์ในการทดสอบได้ด้วย เนื่องจากสิทธิ์แบบละเอียดจะเปิดใช้อยู่เสมอ
-
ตั้งค่าพารามิเตอร์
enable_granular_consent
เป็นtrue
เมื่อเรียกใช้ ปลายทางการให้สิทธิ์ของ Google OAuth SDK บางรายการมีการรองรับพารามิเตอร์นี้อย่างชัดแจ้ง สำหรับแหล่งข้อมูลอื่นๆ โปรดดูเอกสารประกอบเพื่อดูวิธีที่คุณจะเพิ่มพารามิเตอร์นี้และค่าด้วยตนเอง หากการใช้งานของคุณไม่รองรับการเพิ่มพารามิเตอร์ คุณจะสร้างรหัสไคลเอ็นต์ Google OAuth 2.0 สำหรับเว็บ, Android หรือ iOS ใหม่ได้ผ่านคอนโซล Google Cloud เพื่อวัตถุประสงค์ในการทดสอบเท่านั้นตามที่ระบุไว้ในประเด็นก่อนหน้านี้
- เมื่อทดสอบแอปพลิเคชันที่อัปเดตแล้ว ให้ใช้บัญชี Google ส่วนบุคคล (@gmail.com) แทนบัญชี Workspace ทั้งนี้เนื่องจากแอปใน Workspace Enterprise ที่มีการมอบสิทธิ์ทั่วทั้งโดเมนหรือมีการทำเครื่องหมายว่าเชื่อถือได้จะไม่ได้รับผลกระทบจากการเปลี่ยนแปลงสิทธิ์แบบละเอียดในขณะนี้ ดังนั้น การทดสอบด้วยบัญชี Workspace จากองค์กรของคุณอาจไม่แสดงหน้าจอขอความยินยอมแบบละเอียดใหม่ตามที่ตั้งใจไว้