Cách xử lý các quyền chi tiết

Tổng quan

Với các quyền chi tiết, người tiêu dùng có thể kiểm soát chi tiết hơn đối với dữ liệu tài khoản mà họ chọn chia sẻ với từng ứng dụng. Các quyền này mang lại lợi ích cho cả người dùng và nhà phát triển bằng cách cung cấp khả năng kiểm soát, tính minh bạch và tính bảo mật cao hơn. Hướng dẫn này sẽ giúp bạn hiểu rõ những thay đổi và bước cần thiết để cập nhật thành công các ứng dụng của mình nhằm xử lý các quyền chi tiết.

Quyền chi tiết là gì?

Hãy tưởng tượng bạn phát triển một ứng dụng cải thiện hiệu suất và ứng dụng này yêu cầu cả phạm vi email và lịch. Người dùng có thể chỉ muốn sử dụng ứng dụng của bạn cho Lịch Google chứ không phải Gmail. Với quyền OAuth chi tiết, người dùng có thể chọn chỉ cấp quyền cho Google Lịch chứ không cấp quyền cho Gmail. Bằng cách cho phép người dùng cấp quyền truy cập vào dữ liệu cụ thể, điều này sẽ giảm thiểu việc lộ dữ liệu, củng cố niềm tin và trao cho người dùng quyền kiểm soát ưu tiên quyền riêng tư đối với cuộc sống số của họ. Điều quan trọng là bạn phải thiết kế ứng dụng để xử lý những trường hợp như vậy.

Khi có nhiều phạm vi không đăng nhập được yêu cầu

Phạm vi đăng nhập và không đăng nhập

Đối với những ứng dụng yêu cầu cả phạm vi Đăng nhập và không Đăng nhập, trước tiên, người dùng sẽ thấy trang đồng ý cho phạm vi Đăng nhập (email, profileopenid). Sau khi người dùng đồng ý chia sẻ thông tin nhận dạng cơ bản (tên, địa chỉ email và ảnh hồ sơ), người dùng sẽ thấy màn hình đồng ý cấp quyền chi tiết cho các phạm vi không Đăng nhập. Trong trường hợp này, ứng dụng phải kiểm tra những phạm vi mà người dùng cấp và không thể giả định rằng người dùng cấp tất cả các phạm vi được yêu cầu. Trong ví dụ sau, ứng dụng web yêu cầu cả 3 phạm vi Đăng nhập và một phạm vi không Đăng nhập của Google Drive. Sau khi người dùng đồng ý với các phạm vi Đăng nhập, người dùng sẽ thấy màn hình đồng ý cấp quyền chi tiết cho quyền truy cập Google Drive:

Phạm vi đăng nhập và không đăng nhập

Nhiều phạm vi không đăng nhập

Màn hình yêu cầu đồng ý cấp quyền chi tiết sẽ xuất hiện cho người dùng khi các ứng dụng yêu cầu nhiều phạm vi không phải là phạm vi Đăng nhập. Người dùng có thể chọn những quyền mà họ muốn phê duyệt để chia sẻ với ứng dụng. Sau đây là ví dụ về màn hình yêu cầu sự đồng ý theo quyền chi tiết, yêu cầu quyền truy cập vào tin nhắn Gmail và dữ liệu trên Lịch Google của người dùng:

Nhiều phạm vi không đăng nhập

Đối với những ứng dụng chỉ yêu cầu phạm vi Đăng nhập (email, profileopenid), màn hình xin phép cấp quyền ở cấp độ chi tiết sẽ không áp dụng. Người dùng có thể phê duyệt hoặc từ chối toàn bộ yêu cầu đăng nhập. Nói cách khác, nếu các ứng dụng chỉ yêu cầu các phạm vi Đăng nhập (một, hai hoặc cả ba), thì màn hình đồng ý cấp quyền chi tiết sẽ không áp dụng.

Đối với những ứng dụng chỉ yêu cầu một phạm vi không đăng nhập, màn hình đồng ý cấp quyền chi tiết sẽ không áp dụng. Nói cách khác, người dùng sẽ phê duyệt hoặc từ chối toàn bộ yêu cầu và không có hộp đánh dấu nào trong màn hình đồng ý. Bảng sau đây tóm tắt thời điểm màn hình đồng ý cấp quyền chi tiết xuất hiện.

Số lượng phạm vi đăng nhập Số lượng phạm vi Không đăng nhập Màn hình đồng ý cấp quyền chi tiết
1-3 0 Không áp dụng
1-3 1+ Áp dụng
0 1 Không áp dụng
0 2+ Áp dụng

Xác định xem các ứng dụng của bạn có bị ảnh hưởng hay không

Tiến hành xem xét kỹ lưỡng tất cả các phần trong ứng dụng của bạn, nơi các điểm cuối uỷ quyền Google OAuth 2.0 được dùng cho các yêu cầu cấp quyền. Chú ý đến những ứng dụng yêu cầu nhiều phạm vi khi chúng kích hoạt màn hình yêu cầu sự đồng ý cấp quyền chi tiết được trình bày cho người dùng. Trong những trường hợp như vậy, hãy đảm bảo mã của bạn có thể xử lý trường hợp người dùng chỉ uỷ quyền một số phạm vi.

Cách xác định xem ứng dụng của bạn có đang sử dụng nhiều phạm vi hay không

Kiểm tra mã ứng dụng hoặc lệnh gọi mạng đi để xác định xem yêu cầu uỷ quyền Google OAuth 2.0 mà ứng dụng của bạn thực hiện có khiến màn hình đồng ý cấp quyền chi tiết xuất hiện hay không.

Kiểm tra mã ứng dụng

Xem xét các phần trong mã ứng dụng mà bạn đang gọi đến các điểm cuối uỷ quyền Google OAuth để yêu cầu người dùng cấp quyền. Nếu sử dụng một trong các Thư viện ứng dụng API Google, bạn thường có thể tìm thấy những phạm vi mà ứng dụng của bạn yêu cầu trong các bước khởi tạo ứng dụng. Một số ví dụ được trình bày trong phần sau. Bạn nên tham khảo tài liệu về các SDK mà ứng dụng của bạn sử dụng để xử lý Google OAuth 2.0 nhằm xác định xem ứng dụng của bạn có bị ảnh hưởng hay không, bằng cách sử dụng hướng dẫn trong các ví dụ sau đây làm tài liệu tham khảo.

Dịch vụ nhận dạng của Google

Đoạn mã thư viện JavaScript Dịch vụ danh tính của Google sau đây sẽ khởi chạy TokenClient với nhiều phạm vi không đăng nhập. Màn hình yêu cầu sự đồng ý cấp quyền chi tiết sẽ xuất hiện khi ứng dụng web yêu cầu người dùng cấp quyền uỷ quyền.

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

Đoạn mã sau đây sử dụng mô-đun google-auth-oauthlib.flow để tạo yêu cầu uỷ quyền; tham số scope bao gồm 2 phạm vi không đăng nhập. Màn hình yêu cầu sự đồng ý cấp quyền chi tiết sẽ xuất hiện khi ứng dụng web yêu cầu người dùng cấp quyền uỷ quyền.

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

Đoạn mã sau đây tạo một đối tượng google.auth.OAuth2, xác định các tham số trong yêu cầu uỷ quyền mà tham số scope bao gồm 2 phạm vi không đăng nhập. Màn hình yêu cầu sự đồng ý cấp quyền chi tiết sẽ xuất hiện khi ứng dụng web yêu cầu người dùng cấp quyền uỷ quyền.

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
});

Kiểm tra cuộc gọi mạng đi

Phương thức kiểm tra các lệnh gọi mạng sẽ khác nhau tuỳ thuộc vào loại ứng dụng khách của bạn.

Trong khi kiểm tra các lệnh gọi mạng, hãy tìm những yêu cầu được gửi đến điểm cuối uỷ quyền OAuth của Google và kiểm tra tham số scope.

Những giá trị này gây ra màn hình đồng ý cấp quyền chi tiết.

  • Tham số scope chứa các phạm vi Đăng nhập và phạm vi không Đăng nhập.

    Yêu cầu mẫu sau đây chứa cả 3 phạm vi Đăng nhập và một phạm vi không Đăng nhập để xem siêu dữ liệu của các tệp trong Google Drive của người dùng:

    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
  • Tham số scope chứa nhiều phạm vi không đăng nhập.

    Yêu cầu mẫu sau đây chứa 2 phạm vi không phải Đăng nhập để xem siêu dữ liệu Google Drive của người dùng và quản lý các tệp cụ thể trên Google Drive:

  • 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

Các phương pháp hay nhất để xử lý quyền chi tiết

Nếu xác định rằng ứng dụng của bạn cần được cập nhật để xử lý các quyền chi tiết, bạn nên thực hiện các bản cập nhật cần thiết cho mã của mình để xử lý đúng cách sự đồng ý cho nhiều phạm vi. Tất cả các ứng dụng đều phải tuân thủ các phương pháp hay nhất sau đây:

  1. Xem xét Chính sách dữ liệu người dùng của dịch vụ API của Google và đảm bảo bạn tuân thủ các chính sách này.
  2. Yêu cầu các phạm vi cụ thể cần thiết cho một tác vụ. Bạn phải tuân thủ chính sách OAuth 2.0 của Google, tức là bạn chỉ yêu cầu những phạm vi mà bạn cần. Bạn nên tránh yêu cầu nhiều phạm vi khi đăng nhập, trừ phi điều đó là cần thiết cho chức năng cốt lõi của ứng dụng. Việc kết hợp nhiều phạm vi với nhau, đặc biệt là đối với những người dùng lần đầu chưa quen với các tính năng của ứng dụng, có thể khiến họ khó hiểu được nhu cầu cấp các quyền này. Điều này có thể khiến người dùng lo ngại và ngăn họ tiếp tục tương tác với ứng dụng của bạn.
  3. Đưa ra lý do chính đáng cho người dùng trước khi yêu cầu cấp quyền. Giải thích rõ ràng lý do ứng dụng của bạn cần quyền được yêu cầu, bạn sẽ làm gì với dữ liệu của người dùng và người dùng sẽ được lợi như thế nào khi phê duyệt yêu cầu. Nghiên cứu của chúng tôi cho thấy những lời giải thích này giúp tăng độ tin cậy và mức độ tương tác của người dùng.
  4. Sử dụng uỷ quyền gia tăng bất cứ khi nào ứng dụng của bạn yêu cầu các phạm vi để tránh phải quản lý nhiều mã truy cập.
  5. Kiểm tra những phạm vi mà người dùng đã cấp. Khi yêu cầu nhiều phạm vi cùng một lúc, người dùng có thể không cấp tất cả các phạm vi mà ứng dụng của bạn yêu cầu. Ứng dụng của bạn phải luôn kiểm tra xem người dùng đã cấp những phạm vi nào và xử lý mọi trường hợp người dùng từ chối cấp phạm vi bằng cách tắt các tính năng có liên quan. Tuân thủ các chính sách của Google về OAuth 2.0 đối với việc xử lý sự đồng ý cho nhiều phạm vi và chỉ nhắc người dùng đồng ý lại khi họ đã cho thấy rõ ý định sử dụng tính năng cụ thể yêu cầu phạm vi đó.

Cập nhật ứng dụng để xử lý các quyền chi tiết

Ứng dụng Android

Bạn nên tham khảo tài liệu về các SDK mà bạn dùng để tương tác với Google OAuth 2.0 và cập nhật ứng dụng để xử lý các quyền chi tiết dựa trên các phương pháp hay nhất.

Nếu sử dụng SDK auth.api.signin của Dịch vụ Play để tương tác với Google OAuth 2.0, bạn có thể dùng hàm requestPermissions để yêu cầu nhóm phạm vi nhỏ nhất cần thiết và hàm hasPermissions để kiểm tra những phạm vi mà người dùng đã cấp khi yêu cầu quyền chi tiết.

Ứng dụng tiện ích của Chrome

Bạn nên sử dụng Chrome Identity API để làm việc với Google OAuth 2.0 dựa trên các phương pháp hay nhất.

Ví dụ sau đây minh hoạ cách xử lý đúng cách các quyền chi tiết.

manifest.json

Tệp kê khai mẫu khai báo 2 phạm vi không đăng nhập cho ứng dụng tiện ích 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"]
  }
}

Cách tiếp cận không chính xác

Tất cả hoặc không có gì

Người dùng nhấp vào nút này để bắt đầu quy trình uỷ quyền. Đoạn mã giả định rằng người dùng sẽ thấy màn hình đồng ý "chấp nhận tất cả hoặc không chấp nhận" cho 2 phạm vi được chỉ định trong tệp manifest.json. Ứng dụng này không kiểm tra xem người dùng đã cấp quyền truy cập vào những phạm vi nào.

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.
            ...
          }
      });
});

Phương pháp phù hợp

Phạm vi nhỏ nhất

Chọn tập hợp phạm vi nhỏ nhất cần thiết

Ứng dụng chỉ nên yêu cầu tập hợp nhỏ nhất các phạm vi cần thiết. Bạn nên yêu cầu ứng dụng của mình yêu cầu một phạm vi tại một thời điểm khi cần thiết để hoàn thành một tác vụ.

Trong ví dụ này, giả sử cả hai phạm vi được khai báo trong tệp manifest.json đều là tập hợp phạm vi nhỏ nhất cần thiết. Tệp oauth.js sử dụng Chrome Identity API để bắt đầu quy trình uỷ quyền với Google. Bạn nên chọn bật quyền chi tiết để người dùng có nhiều quyền kiểm soát hơn khi cấp quyền cho ứng dụng của bạn. Ứng dụng của bạn phải xử lý phản hồi của người dùng một cách thích hợp bằng cách kiểm tra những phạm vi mà người dùng cho phép.

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
              ...
            }
          }
      });
});

Ứng dụng iOS, iPadOS và macOS

Bạn nên tham khảo tài liệu về các SDK mà bạn dùng để tương tác với Google OAuth 2.0 và cập nhật ứng dụng để xử lý các quyền chi tiết dựa trên các phương pháp hay nhất.

Nếu sử dụng thư viện Đăng nhập bằng Google cho iOS và macOS để tương tác với Google OAuth 2.0, bạn nên xem tài liệu về cách xử lý các quyền chi tiết.

Ứng dụng web

Bạn nên tham khảo tài liệu về các SDK mà bạn dùng để tương tác với Google OAuth 2.0 và cập nhật ứng dụng để xử lý các quyền chi tiết dựa trên các phương pháp hay nhất.

Quyền truy cập phía máy chủ (khi không có mạng)

Chế độ truy cập phía máy chủ (ngoại tuyến) yêu cầu bạn làm như sau:
  • Thiết lập một máy chủ và xác định một điểm cuối có thể truy cập công khai để nhận mã uỷ quyền.
  • Định cấu hình URI chuyển hướng của điểm cuối công khai trong Clients page của Google Cloud Console.

Đoạn mã sau đây cho thấy một ví dụ về NodeJS yêu cầu 2 phạm vi không đăng nhập. Người dùng sẽ thấy màn hình yêu cầu đồng ý cấp quyền chi tiết.

Cách tiếp cận không chính xác

Tất cả hoặc không có gì

Người dùng được chuyển hướng đến URL uỷ quyền. Đoạn mã giả định rằng người dùng sẽ thấy màn hình đồng ý "tất cả hoặc không có gì" cho 2 phạm vi được chỉ định trong mảng scopes. Ứng dụng này không kiểm tra xem người dùng đã cấp quyền truy cập vào những phạm vi nào.

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);
}
Phương pháp phù hợp

Phạm vi nhỏ nhất

Chọn tập hợp phạm vi nhỏ nhất cần thiết

Ứng dụng chỉ nên yêu cầu tập hợp nhỏ nhất các phạm vi cần thiết. Bạn nên yêu cầu ứng dụng của mình yêu cầu một phạm vi tại một thời điểm khi cần thiết để hoàn thành một tác vụ. Bất cứ khi nào yêu cầu các phạm vi, ứng dụng của bạn đều phải sử dụng uỷ quyền gia tăng để tránh phải quản lý nhiều mã truy cập.

Nếu ứng dụng của bạn phải yêu cầu nhiều phạm vi không phải là phạm vi Đăng nhập, thì bạn luôn phải sử dụng uỷ quyền gia tăng khi yêu cầu và kiểm tra xem người dùng đã cấp phạm vi nào.

Trong ví dụ này, giả sử cả hai phạm vi đã nêu đều cần thiết để ứng dụng hoạt động đúng cách. Bạn nên chọn bật quyền chi tiết để người dùng có nhiều quyền kiểm soát hơn khi cấp quyền cho ứng dụng của bạn. Ứng dụng của bạn phải xử lý đúng phản hồi của người dùng bằng cách kiểm tra những phạm vi mà họ đã uỷ quyền.

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);
}

Xem hướng dẫn về ứng dụng web phía máy chủ để biết cách truy cập vào các API của Google từ các ứng dụng dựa trên máy chủ.

Chỉ có quyền truy cập phía máy khách

  • Đối với những ứng dụng sử dụng thư viện JavaScript Dịch vụ nhận dạng của Google để tương tác với Google OAuth 2.0, bạn nên xem tài liệu này về cách xử lý các quyền chi tiết.
  • Đối với những ứng dụng trực tiếp thực hiện các lệnh gọi bằng JavaScript đến các điểm cuối uỷ quyền OAuth 2.0 của Google, bạn nên xem tài liệu này về cách xử lý các quyền chi tiết.

Kiểm thử ứng dụng đã cập nhật của bạn về cách xử lý các quyền ở cấp độ chi tiết

  1. Nêu khái quát tất cả các trường hợp mà người dùng có thể phản hồi yêu cầu cấp quyền và hành vi dự kiến của ứng dụng. Ví dụ: nếu người dùng chỉ cho phép 2 trong số 3 phạm vi được yêu cầu, thì ứng dụng của bạn sẽ hoạt động tương ứng.
  2. Kiểm thử ứng dụng của bạn khi bật quyền chi tiết. Có 2 cách để bật quyền chi tiết:
    1. Kiểm tra màn hình xin phép bằng OAuth 2.0 của ứng dụng để xem quyền ở cấp độ chi tiết đã được bật cho ứng dụng của bạn hay chưa. Bạn cũng có thể tạo một mã ứng dụng khách Google OAuth 2.0 mới cho Web, Android hoặc iOS thông qua bảng điều khiển Google Cloud cho mục đích kiểm thử vì quyền chi tiết luôn được bật cho các mã ứng dụng khách này.
    2. Đặt tham số enable_granular_consent thành true khi gọi các điểm cuối uỷ quyền OAuth của Google. Một số SDK có hỗ trợ rõ ràng cho tham số này. Đối với những người khác, hãy xem tài liệu để biết cách thêm thông số này và giá trị của thông số theo cách thủ công. Nếu quá trình triển khai của bạn không hỗ trợ việc thêm tham số, bạn có thể tạo một mã ứng dụng Google OAuth 2.0 mới cho Web, Android hoặc iOS thông qua Google Cloud Console chỉ cho mục đích kiểm thử như đã nêu ở điểm trước.
  3. Khi kiểm thử ứng dụng đã cập nhật, hãy sử dụng Tài khoản Google cá nhân (@gmail.com) thay vì tài khoản Workspace. Lý do là các ứng dụng Workspace Enterprise có quyền uỷ quyền trên toàn miền hoặc được đánh dấu là Đáng tin cậy hiện không bị ảnh hưởng bởi những thay đổi đối với quyền chi tiết. Do đó, việc kiểm thử bằng tài khoản Workspace của tổ chức có thể không hiển thị màn hình đồng ý chi tiết mới như dự kiến.