Sử dụng mô hình mã thông báo

Thư viện JavaScript google.accounts.oauth2 giúp bạn nhắc người dùng đồng ý và lấy mã truy cập để làm việc với dữ liệu người dùng. Chiến dịch này dựa trên Quy trình cấp quyền ngầm OAuth 2.0 và được thiết kế để cho phép bạn gọi Google API trực tiếp bằng REST và CORS hoặc để dùng thư viện ứng dụng API của Google cho JavaScript (còn được gọi là gapi.client) để giúp bạn truy cập đơn giản, linh hoạt vào các API phức tạp hơn.

Người dùng trên trang web của bạn sẽ kích hoạt dữ liệu người dùng được bảo vệ qua một trình duyệt trước khi họ truy cập vào dữ liệu đó Trình chọn tài khoản dựa trên web của Google, các quy trình đăng nhập và sự đồng ý của Google cùng với Máy chủ OAuth của Google gặp sự cố và trả về mã truy cập cho ứng dụng web của bạn.

Trong mô hình uỷ quyền dựa trên mã thông báo, bạn không cần lưu trữ dữ liệu cho mỗi người dùng làm mới mã thông báo trên máy chủ phụ trợ.

Bạn nên làm theo phương pháp được nêu ở đây thay vì các kỹ thuật được sử dụng trong OAuth 2.0 cũ hơn cho ứng dụng web phía máy khách của chúng tôi.

Thiết lập

Tìm hoặc tạo mã ứng dụng khách bằng cách làm theo các bước được mô tả trong bài viết Lấy Hướng dẫn về mã ứng dụng khách Google API. Tiếp theo, hãy thêm thư viện ứng dụng vào các trang trên trang web của bạn sẽ gọi API Google. Cuối cùng, hãy khởi chạy mã thông báo khách hàng. Thông thường, việc này được thực hiện trong trình xử lý onload của thư viện ứng dụng.

Khởi chạy một ứng dụng mã thông báo

Gọi initTokenClient() để khởi chạy một ứng dụng mã thông báo mới bằng client ID, bạn có thể bao gồm danh sách một hoặc nhiều phạm vi người dùng (không bắt buộc) cần truy cập:

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

Kích hoạt quy trình mã thông báo OAuth 2.0

Sử dụng phương thức requestAccessToken() để kích hoạt luồng mã thông báo trải nghiệm người dùng và lấy một mã truy cập. Google sẽ nhắc người dùng:

  • Chọn tài khoản của trẻ,
  • đăng nhập vào Tài khoản Google nếu chưa đăng nhập,
  • cho phép ứng dụng web của bạn truy cập vào từng phạm vi được yêu cầu.

Một cử chỉ của người dùng sẽ kích hoạt luồng mã thông báo: <button onclick="client.requestAccessToken();">Authorize me</button>

Sau đó, Google sẽ trả về một TokenResponse chứa mã truy cập và danh sách phạm vi mà người dùng đã cấp quyền truy cập, hoặc lỗi, cho trình xử lý gọi lại của bạn.

Người dùng có thể đóng cửa sổ trình chọn tài khoản hoặc đăng nhập, trong trường hợp đó hàm callback sẽ không được gọi.

Thiết kế và trải nghiệm người dùng cho ứng dụng của bạn chỉ nên được triển khai sau xem xét kỹ Các chính sách OAuth 2.0 của Google. Những chính sách này bao gồm làm việc với nhiều phạm vi, về thời điểm và cách xử lý sự đồng ý của người dùng, v.v.

Uỷ quyền gia tăng là một chính sách và phương pháp thiết kế ứng dụng được dùng để yêu cầu quyền truy cập vào tài nguyên, sử dụng phạm vi, chỉ khi cần thay vì trả trước và tất cả cùng một lúc. Người dùng có thể phê duyệt hoặc từ chối việc chia sẻ từng tài nguyên mà ứng dụng của bạn yêu cầu, đây được gọi là các quyền chi tiết.

Trong quá trình này, Google sẽ nhắc người dùng đồng ý, liệt kê từng yếu tố phạm vi yêu cầu, người dùng chọn tài nguyên được chia sẻ với ứng dụng của bạn và Cuối cùng, Google sẽ gọi hàm callback để trả về một Người dùng và Mã truy cập các phạm vi được chấp thuận. Sau đó, ứng dụng của bạn xử lý nhiều loại kết quả một cách an toàn với các quyền chi tiết.

Uỷ quyền tăng dần

Đối với ứng dụng web, 2 tình huống cấp cao sau đây thể hiện mức độ gia tăng uỷ quyền bằng:

  • Ứng dụng Ajax một trang, thường sử dụng XMLHttpRequest với quyền truy cập động vào của chúng tôi.
  • Nhiều trang web, tài nguyên được phân tách và quản lý trên từng trang.

Hai tình huống này được trình bày để minh hoạ những điều cần cân nhắc khi thiết kế và , nhưng không phải là đề xuất toàn diện về cách để tạo sự đồng ý trong ứng dụng của bạn. Ứng dụng trong thế giới thực có thể sử dụng một biến thể hoặc kết hợp các kỹ thuật này.

Ajax

Thêm tính năng hỗ trợ cho việc uỷ quyền dần dần cho ứng dụng của bạn bằng cách thực hiện nhiều lệnh gọi vào requestAccessToken() và sử dụng đối tượng OverridableTokenClientConfig scope để yêu cầu từng phạm vi tại thời điểm cần thiết và chỉ khi cần thiết. Trong ví dụ này, các tài nguyên sẽ được yêu cầu và hiển thị chỉ sau khi cử chỉ của người dùng mở rộng phần nội dung đã thu gọn.

Ứng dụng Ajax
Khởi chạy ứng dụng mã thông báo khi tải trang:
        const client = google.accounts.oauth2.initTokenClient({
          client_id: 'YOUR_GOOGLE_CLIENT_ID',
          callback: "onTokenResponse",
        });
      
Yêu cầu sự đồng ý và lấy mã truy cập thông qua cử chỉ của người dùng, nhấp vào `+` để mở:

Tài liệu cần đọc

Hiển thị các tài liệu gần đây

          client.requestAccessToken(
            overrideConfig = ({
               scope = 'https://www.googleapis.com/auth/documents.readonly'
             })
           );
        

Sự kiện sắp tới

Hiển thị thông tin lịch

          client.requestAccessToken(
            overrideConfig = ({
               scope = 'https://www.googleapis.com/auth/calendar.readonly'
             })
           );
        

Hiển thị ảnh

          client.requestAccessToken(
            overrideConfig = ({
               scope = 'https://www.googleapis.com/auth/photoslibrary.readonly'
             })
           );
        

Mỗi lệnh gọi đến requestAccessToken kích hoạt một khoảnh khắc đồng ý của người dùng, ứng dụng của bạn sẽ chỉ có quyền truy cập vào những tài nguyên bắt buộc theo phần mà người dùng chọn mở rộng, do đó hạn chế việc chia sẻ tài nguyên thông qua lựa chọn của người dùng.

Nhiều trang web

Khi thiết kế để uỷ quyền gia tăng, nhiều trang được dùng để yêu cầu chỉ(các) phạm vi cần thiết để tải trang, giảm độ phức tạp và nhu cầu thực hiện nhiều lệnh gọi để có được sự đồng ý của người dùng và truy xuất mã truy cập.

Ứng dụng nhiều trang
Trang web
Trang 1. Tài liệu nên đọc
  const client = google.accounts.oauth2.initTokenClient({
    client_id: 'YOUR_GOOGLE_CLIENT_ID',
    callback: "onTokenResponse",
    scope: 'https://www.googleapis.com/auth/documents.readonly',
  });
  client.requestAccessToken();
          
Trang 2. Sự kiện sắp tới
  const client = google.accounts.oauth2.initTokenClient({
    client_id: 'YOUR_GOOGLE_CLIENT_ID',
    callback: "onTokenResponse",
    scope: 'https://www.googleapis.com/auth/calendar.readonly',
  });
  client.requestAccessToken();
          
Trang 3. Băng chuyền ảnh
  const client = google.accounts.oauth2.initTokenClient({
    client_id: 'YOUR_GOOGLE_CLIENT_ID',
    callback: "onTokenResponse",
    scope: 'https://www.googleapis.com/auth/photoslibrary.readonly',
  });
  client.requestAccessToken();
          

Mỗi trang yêu cầu phạm vi cần thiết và lấy mã truy cập bằng cách gọi initTokenClient()requestAccessToken() trong thời gian tải. Trong trường hợp này, các trang web riêng lẻ được sử dụng để tách biệt rõ ràng chức năng người dùng và tài nguyên theo phạm vi. Trong tình huống thực tế, các trang riêng lẻ có thể yêu cầu nhiều phạm vi liên quan.

Các quyền chi tiết

Các quyền chi tiết được xử lý như nhau trong mọi trường hợp; sau đó requestAccessToken() gọi hàm callback và một mã truy cập trả về, hãy kiểm tra để đảm bảo rằng người dùng đã phê duyệt phạm vi được yêu cầu bằng cách sử dụng hasGrantedAllScopes() hoặc hasGrantedAnyScope(). Ví dụ:

const client = google.accounts.oauth2.initTokenClient({
  client_id: 'YOUR_GOOGLE_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly \
          https://www.googleapis.com/auth/documents.readonly \
          https://www.googleapis.com/auth/photoslibrary.readonly',
  callback: (tokenResponse) => {
    if (tokenResponse && tokenResponse.access_token) {
      if (google.accounts.oauth2.hasGrantedAnyScope(tokenResponse,
          'https://www.googleapis.com/auth/photoslibrary.readonly')) {
        // Look at pictures
        ...
      }
      if (google.accounts.oauth2.hasGrantedAllScopes(tokenResponse,
          'https://www.googleapis.com/auth/calendar.readonly',
          'https://www.googleapis.com/auth/documents.readonly')) {
        // Meeting planning and review documents
        ...
      }
    }
  },
});

Mọi khoản tiền tài trợ đã được chấp nhận trước đó trong các phiên hoạt động hoặc yêu cầu trước đó cũng sẽ được đưa vào phản hồi. Hồ sơ về sự đồng ý của người dùng được duy trì cho mỗi người dùng và Mã ứng dụng khách và vẫn tồn tại trên nhiều lệnh gọi đến initTokenClient() hoặc requestAccessToken() Theo mặc định, chỉ cần sự đồng ý của người dùng là khi người dùng truy cập trang web của bạn và yêu cầu phạm vi mới nhưng có thể được yêu cầu vào mỗi lần tải trang bằng cách sử dụng prompt=consent trong các đối tượng cấu hình Máy khách mã thông báo.

Xử lý mã thông báo

Trong mô hình Mã thông báo, mã truy cập không được hệ điều hành hoặc trình duyệt lưu trữ mà thay vào đó mã thông báo mới được thu thập lần đầu tại thời điểm tải trang hoặc sau đó bằng cách kích hoạt gọi đến requestAccessToken() thông qua một cử chỉ của người dùng, chẳng hạn như nhấn nút.

Sử dụng REST và CORS với các API của Google

Bạn có thể dùng mã truy cập để gửi yêu cầu đã xác thực đến các API của Google bằng cách sử dụng REST và CORS. Quyền này cho phép người dùng đăng nhập, đồng ý và Google phát hành mã truy cập và trang web của bạn để làm việc với dữ liệu của người dùng.

Trong ví dụ này, hãy xem sự kiện trên lịch sắp tới của người dùng đã đăng nhập bằng cách sử dụng mã truy cập do tokenRequest() trả về:

var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.googleapis.com/calendar/v3/calendars/primary/events');
xhr.setRequestHeader('Authorization', 'Bearer ' + tokenResponse.access_token);
xhr.send();

Xem Cách sử dụng CORS để truy cập API của Google để biết thêm.

Phần tiếp theo trình bày cách dễ dàng tích hợp với các API phức tạp hơn.

Làm việc với thư viện JavaScript API của Google

Ứng dụng mã thông báo hoạt động với Thư viện ứng dụng API của Google cho JavaScript Xem đoạn mã dưới đây.

const client = google.accounts.oauth2.initTokenClient({
  client_id: 'YOUR_GOOGLE_CLIENT_ID',
  scope: 'https://www.googleapis.com/auth/calendar.readonly',
  callback: (tokenResponse) => {
    if (tokenResponse && tokenResponse.access_token) {
      gapi.client.setApiKey('YOUR_API_KEY');
      gapi.client.load('calendar', 'v3', listUpcomingEvents);
    }
  },
});

function listUpcomingEvents() {
  gapi.client.calendar.events.list(...);
}

Thời hạn của mã thông báo

Theo thiết kế, mã truy cập có thời gian tồn tại ngắn. Nếu mã truy cập hết hạn trước khi kết thúc phiên của người dùng, lấy mã thông báo mới bằng cách gọi requestAccessToken() trong một sự kiện do người dùng thực hiện, chẳng hạn như nhấn nút.

Gọi phương thức google.accounts.oauth2.revoke để xoá sự đồng ý của người dùng và quyền truy cập vào các tài nguyên ở tất cả phạm vi được cấp cho ứng dụng của bạn. Quyền truy cập hợp lệ cần có mã thông báo để thu hồi quyền này:

google.accounts.oauth2.revoke('414a76cb127a7ece7ee4bf287602ca2b56f8fcbf7fcecc2cd4e0509268120bd7', done => {
    console.log(done);
    console.log(done.successful);
    console.log(done.error);
    console.log(done.error_description);
  });