Di chuyển sang Dịch vụ nhận dạng của Google

Sử dụng bộ sưu tập để sắp xếp ngăn nắp các trang Lưu và phân loại nội dung dựa trên lựa chọn ưu tiên của bạn.

Tổng quan

Để có được mã truy cập cho mỗi người dùng để gọi API của Google, Google cung cấp nhiều thư viện JavaScript:

Hướng dẫn này cung cấp hướng dẫn di chuyển từ các thư viện này sang thư viện Dịch vụ nhận dạng của Google.

Bằng cách làm theo hướng dẫn này, bạn sẽ:

  • thay thế Thư viện nền tảng không dùng nữa bằng thư viện Dịch vụ nhận dạng, và
  • nếu bạn sử dụng Thư viện ứng dụng API, hãy xoá mô-đun gapi.auth2 không dùng nữa, các phương thức và đối tượng của mô-đun đó, thay thế bằng các mô-đun Dịch vụ nhận dạng tương đương.

Để biết nội dung mô tả về những thay đổi đối với thư viện JavaScript của Dịch vụ nhận dạng, hãy đọc tổng quancách thức hoạt động của tính năng uỷ quyền người dùng để xem lại các thuật ngữ và khái niệm chính.

Nếu bạn đang tìm cách xác thực thông tin đăng nhập và đăng nhập của người dùng, hãy xem phần Di chuyển từ Google Đăng nhập.

Xác định quy trình uỷ quyền

Có thể có 2 luồng uỷ quyền người dùng: mã uỷ quyền ngầm ẩn và mã uỷ quyền.

Xem lại ứng dụng web để xác định loại quy trình uỷ quyền đang được sử dụng.

Chỉ báo rằng ứng dụng web của bạn đang sử dụng quy trình ngầm ẩn:

  • Ứng dụng web của bạn chỉ chạy dựa trên trình duyệt và không có nền tảng phụ trợ.
  • Người dùng phải có mặt để gọi API Google, ứng dụng của bạn chỉ sử dụng mã thông báo truy cập và không yêu cầu mã làm mới.
  • Ứng dụng web của bạn tải apis.google.com/js/api.js.
  • Quá trình triển khai của bạn dựa trên OAuth 2.0 dành cho ứng dụng web phía máy khách.
  • Ứng dụng của bạn sử dụng các mô-đun gapi.client hoặc gapi.auth2 có trong Thư viện ứng dụng API của Google cho JavaScript.

Chỉ báo rằng ứng dụng web của bạn đang sử dụng quy trình mã uỷ quyền:

  • Quá trình triển khai của bạn dựa trên:

  • Ứng dụng sẽ thực thi cả trong trình duyệt của người dùng và trên nền tảng phụ trợ của bạn.

  • Nền tảng phụ trợ của bạn lưu trữ một điểm cuối mã uỷ quyền.

  • Nền tảng phụ trợ của bạn thay mặt người dùng gọi API Google mà không yêu cầu họ phải có mặt, còn được gọi là chế độ ngoại tuyến.

  • Mã làm mới được quản lý và lưu trữ trên nền tảng phụ trợ của bạn.

Trong một số trường hợp, cơ sở mã của bạn có thể hỗ trợ cả hai luồng.

Chọn quy trình cấp phép

Trước khi bắt đầu di chuyển, bạn cần xác định xem việc tiếp tục với luồng hiện có hay sử dụng một luồng khác đáp ứng tốt nhất nhu cầu của bạn.

Xem lại phần chọn quy trình ủy quyền để hiểu sự khác biệt chính và đánh đổi giữa hai quy trình.

Trong hầu hết các trường hợp, quy trình mã uỷ quyền được đề xuất vì quy trình này cung cấp mức độ bảo mật cao nhất cho người dùng. Việc triển khai quy trình này cũng cho phép nền tảng của bạn dễ dàng thêm các chức năng ngoại tuyến mới, chẳng hạn như tìm nạp nội dung cập nhật để thông báo cho người dùng về những thay đổi đáng chú ý đối với lịch, ảnh, gói thuê bao, v.v.

Chọn quy trình uỷ quyền bằng cách sử dụng các bộ chọn bên dưới.

Luồng ngầm ẩn

Lấy mã truy cập để sử dụng trong trình duyệt khi người dùng đang có mặt.

Ví dụ về luồng ngầm ẩn cho thấy các ứng dụng web trước và sau khi di chuyển sang Dịch vụ nhận dạng.

Luồng mã uỷ quyền

Mã uỷ quyền cho mỗi người dùng do Google phát hành được phân phối cho nền tảng phụ trợ của bạn, sau đó mã đó được trao đổi để lấy mã truy cập và mã làm mới.

Ví dụ về quy trình mã uỷ quyền hiển thị các ứng dụng web trước và sau khi di chuyển sang Dịch vụ nhận dạng.

Trong suốt hướng dẫn này, hãy làm theo các hướng dẫn được in đậm để Thêm, Xoá, Cập nhật hoặc Thay thế chức năng hiện có.

Thay đổi đối với ứng dụng web trong trình duyệt của bạn

Phần này xem xét những thay đổi bạn sẽ thực hiện đối với ứng dụng web trong trình duyệt khi di chuyển sang thư viện JavaScript Dịch vụ nhận dạng của Google.

Xác định mã bị ảnh hưởng và kiểm thử

Cookie gỡ lỗi có thể giúp xác định vị trí mã bị ảnh hưởng và để kiểm tra hành vi sau khi ngừng sử dụng.

Trong các ứng dụng lớn hoặc phức tạp, bạn có thể gặp khó khăn khi tìm thấy tất cả mã bị ảnh hưởng bởi việc không dùng mô-đun gapi.auth2 nữa. Để ghi lại nhật ký sử dụng sớm chức năng không còn được dùng nữa vào bảng điều khiển, hãy đặt giá trị của cookie G_AUTH2_MIGRATION thành informational. Nếu muốn, bạn có thể thêm dấu hai chấm, theo sau là giá trị khoá để ghi nhật ký vào bộ nhớ của phiên hoạt động. Sau khi đăng nhập và nhận đánh giá thông tin xác thực hoặc gửi nhật ký đã thu thập đến phần phụ trợ để phân tích sau. Ví dụ: informational:showauth2use lưu nguồn gốc và URL vào khoá lưu trữ phiên có tên showauth2use.

Để xác minh hành vi của ứng dụng khi mô-đun gapi.auth2 không còn được tải, hãy đặt giá trị của cookie G_AUTH2_MIGRATION thành enforced. Điều này cho phép kiểm thử hành vi sau khi ngừng sử dụng trước ngày thực thi.

Các giá trị cookie G_AUTH2_MIGRATION có thể có:

  • enforced Không tải mô-đun gapi.auth2.
  • informational Ghi nhật ký sử dụng chức năng không dùng nữa vào bảng điều khiển JS. Ngoài ra, hãy ghi nhật ký bộ nhớ phiên khi tên khoá không bắt buộc được đặt: informational:key-name.

Để giảm thiểu tác động đến người dùng, bạn nên đặt cookie này cục bộ trong quá trình phát triển và thử nghiệm trước khi sử dụng trong môi trường phát hành chính thức.

Thư viện và mô-đun

Mô-đun gapi.auth2 quản lý quy trình xác thực người dùng để đăng nhập và quy trình ngầm ẩn để uỷ quyền, thay thế mô-đun không dùng nữa này cũng như các đối tượng và phương thức của mô-đun đó với thư viện Dịch vụ nhận dạng của Google.

Thêm thư viện Dịch vụ nhận dạng vào ứng dụng web bằng cách đưa thư viện đó vào tài liệu của bạn:

<script src="https://accounts.google.com/gsi/client" async defer></script>

Xoá mọi bản sao tải mô-đun auth2 bằng gapi.load('auth2', function).

Thư viện Dịch vụ nhận dạng của Google thay thế việc sử dụng mô-đun gapi.auth2. Bạn có thể yên tâm tiếp tục sử dụng mô-đun gapi.client của Thư viện ứng dụng API của Google cho JavaScript, đồng thời tận dụng tính năng tự động tạo phương thức JS có thể gọi từ một tài liệu khám phá, phân nhóm nhiều lệnh gọi API và chức năng quản lý CORS.

Số lượng cookie

Sự cho phép của người dùng không yêu cầu sử dụng cookie.

Xem phần Di chuyển từ tính năng Đăng nhập bằng Google để biết thông tin chi tiết về cách xác thực người dùng sử dụng cookie và Cách Google sử dụng cookie để sử dụng cookie bởi các sản phẩm và dịch vụ khác của Google.

Thông tin xác thực

Dịch vụ nhận dạng của Google phân tách việc xác thực và cấp phép người dùng thành hai

Để xem những thay đổi này, hãy xem thông tin xác thực mẫu.

Luồng ngầm ẩn

Tách quyền xác thực và ủy quyền người dùng bằng cách xóa xử lý hồ sơ người dùng khỏi các luồng ủy quyền.

Hãy xoá những tài liệu tham khảo về ứng dụng JavaScript đăng nhập bằng Google này:

Phương pháp

  • GoogleUser.getBasicProfile()
  • GoogleUser.getId()

Luồng mã uỷ quyền

Dịch vụ nhận dạng phân tách thông tin xác thực trong trình duyệt thành mã thông báo mã nhận dạng và mã thông báo truy cập. Thay đổi này không áp dụng cho thông tin xác thực thu được thông qua các lệnh gọi trực tiếp đến điểm cuối Google OAuth 2.0 từ nền tảng phụ trợ hoặc thông qua thư viện chạy trên máy chủ bảo mật trên nền tảng của bạn, chẳng hạn như Ứng dụng API Google Node.js.

Trạng thái phiên

Trước đây, tính năng Đăng nhập bằng Google đã giúp bạn quản lý trạng thái đăng nhập của người dùng bằng:

Bạn chịu trách nhiệm quản lý trạng thái đăng nhập và phiên hoạt động của người dùng trong ứng dụng web của mình.

Hãy xoá những tài liệu tham khảo về ứng dụng JavaScript đăng nhập bằng Google này:

Đối tượng:

  • gapi.auth2.SignInOptions

Phương thức:

  • GoogleAuth.attachClickHandler()
  • GoogleAuth.isSignedIn()
  • GoogleAuth.isSignedIn.get()
  • GoogleAuth.isSignedIn.listen()
  • GoogleAuth.signIn()
  • GoogleAuth.signOut()
  • GoogleAuth.currentUser.get()
  • GoogleAuth.currentUser.listen()
  • GoogleUser.isSignedIn()

Cấu hình ứng dụng

Cập nhật ứng dụng web của bạn để khởi động một ứng dụng mã thông báo cho luồng mã ngầm ẩn hoặc ngầm định.

Hãy xoá những tài liệu tham khảo về ứng dụng JavaScript đăng nhập bằng Google này:

Đối tượng:

  • gapi.auth2.ClientConfig
  • gapi.auth2.OfflineAccessOptions

Phương thức:

  • gapi.auth2.getAuthInstance()
  • GoogleUser.grant()

Luồng ngầm ẩn

Thêm đối tượng TokenClientConfig và lệnh gọi initTokenClient() để định cấu hình ứng dụng web, làm theo ví dụ trong phần khởi chạy ứng dụng mã thông báo.

Thay thế Các tệp đối chiếu JavaScript dành cho tính năng Đăng nhập bằng Google bằng Dịch vụ nhận dạng của Google:

Đối tượng:

  • gapi.auth2.AuthorizeConfigTokenClientConfig

Phương thức:

  • gapi.auth2.init()google.accounts.oauth2.initTokenClient()

Các tham số:

  • gapi.auth2.AuthorizeConfig.login_hint bằng TokenClientConfig.hint.
  • gapi.auth2.GoogleUser.getHostedDomain() bằng TokenClientConfig.hosted_domain.

Luồng mã uỷ quyền

Thêm đối tượng CodeClientConfig và lệnh gọi initCodeClient() để định cấu hình ứng dụng web, làm theo ví dụ trong khởi chạy ứng dụng mã.

Khi chuyển từ ngầm ẩn sang luồng mã uỷ quyền:

Xoá Các tệp tham chiếu JavaScript của chương trình Đăng nhập bằng Google

Đối tượng:

  • gapi.auth2.AuthorizeConfig

Phương thức:

  • gapi.auth2.init()

Các tham số:

  • gapi.auth2.AuthorizeConfig.login_hint
  • gapi.auth2.GoogleUser.getHostedDomain()

Yêu cầu mã thông báo

Một cử chỉ của người dùng, chẳng hạn như lượt nhấp vào nút, tạo ra một yêu cầu dẫn đến việc một mã truy cập được trả về trực tiếp cho trình duyệt của người dùng bằng luồng ngầm ẩn, hoặc đến nền tảng phụ trợ của bạn sau khi trao đổi mã uỷ quyền cho mỗi người dùng để lấy mã truy cập và mã làm mới.

Luồng ngầm ẩn

Bạn có thể lấy và sử dụng mã thông báo truy cập trong trình duyệt khi người dùng đang đăng nhập và có một phiên hoạt động với Google. Đối với chế độ ngầm ẩn, một cử chỉ của người dùng bắt buộc phải yêu cầu mã truy cập, ngay cả khi có yêu cầu trước đó.

Thay thế Các tệp tham chiếu JavaScript đăng nhập bằng Google: bằng Dịch vụ nhận dạng của Google:

Phương thức:

  • gapi.auth2.authorize()TokenClient.requestAccessToken()
  • GoogleUser.reloadAuthResponse()TokenClient.requestAccessToken()

Thêm một đường liên kết hoặc nút để gọi requestAccessToken() nhằm bắt đầu luồng trải nghiệm người dùng bật lên để yêu cầu mã truy cập hoặc để lấy mã thông báo mới khi mã thông báo hiện có hết hạn.

Cập nhật cơ sở mã của bạn để:

  • Kích hoạt quy trình mã thông báo OAuth 2.0 bằng requestAccessToken().
  • Hỗ trợ uỷ quyền gia tăng bằng cách sử dụng requestAccessTokenOverridableTokenClientConfig để tách một yêu cầu cho nhiều phạm vi thành nhiều yêu cầu nhỏ hơn.
  • Yêu cầu mã thông báo mới khi mã hiện tại hết hạn hoặc bị thu hồi.

Khi làm việc với nhiều phạm vi, bạn có thể phải thay đổi cấu trúc đối với cơ sở mã của mình để chỉ yêu cầu quyền truy cập vào các phạm vi khi cần chứ không phải tất cả các phạm vi cùng một lúc, được gọi là ủy quyền gia tăng. Mỗi yêu cầu phải chứa nhiều phạm vi nhất có thể và tốt nhất là một phạm vi duy nhất. Xem cách xử lý sự đồng ý của người dùng để biết thêm thông tin về cách cập nhật ứng dụng để tăng cường uỷ quyền.

Khi một mã truy cập hết hạn, mô-đun gapi.auth2 sẽ tự động lấy một mã truy cập hợp lệ mới cho ứng dụng web của bạn. Để tăng cường bảo mật cho người dùng, quy trình làm mới mã thông báo tự động này không được thư viện Dịch vụ nhận dạng của Google hỗ trợ. Bạn phải cập nhật ứng dụng web của mình để phát hiện một mã truy cập đã hết hạn và yêu cầu một mã truy cập mới. Hãy xem phần Xử lý mã thông báo bên dưới để biết thêm thông tin.

Luồng mã uỷ quyền

Thêm một đường liên kết hoặc nút để gọi requestCode() nhằm yêu cầu Google cấp mã uỷ quyền. Để biết ví dụ, hãy xem phần Luồng mã OAuth 2.0 cho Trình kích hoạt.

Hãy xem phần Xử lý mã thông báo bên dưới để biết thêm thông tin về cách phản hồi mã truy cập đã hết hạn hoặc bị thu hồi.

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

Thêm xử lý lỗi để phát hiện các lệnh gọi API Google không thành công khi sử dụng mã truy cập đã hết hạn hoặc bị thu hồi, và để yêu cầu mã truy cập hợp lệ mới.

Mã trạng thái HTTP của 401 Unauthorized và thông báo lỗi invalid_token sẽ được API của Google trả về khi mã thông báo truy cập đã hết hạn hoặc bị thu hồi được sử dụng. Để biết ví dụ, hãy xem phần Phản hồi của mã thông báo không hợp lệ.

Mã thông báo đã hết hạn

Mã truy cập có thời hạn ngắn và thường chỉ có hiệu lực trong vài phút.

Thu hồi mã thông báo

Chủ sở hữu Tài khoản Google có thể thu hồi sự đồng ý đã cấp trước đó bất cứ lúc nào. Làm như vậy sẽ vô hiệu hoá mã truy cập và mã làm mới hiện có. Tính năng thu hồi có thể được kích hoạt từ nền tảng của bạn bằng cách sử dụng revoke() hoặc thông qua một Tài khoản Google.

Thay thế Các tệp tham chiếu JavaScript đăng nhập bằng Google: bằng Dịch vụ nhận dạng của Google:

Phương thức:

  • getAuthInstance().disconnect()google.accounts.oauth2.revoke()
  • GoogleUser.disconnect()google.accounts.oauth2.revoke()

Gọi revoke khi người dùng xoá tài khoản của họ trên nền tảng của bạn hoặc muốn xoá sự đồng ý để chia sẻ dữ liệu với ứng dụng của bạn.

Google sẽ hiển thị hộp thoại đồng ý cho người dùng khi ứng dụng web hoặc nền tảng phụ trợ yêu cầu mã truy cập. Xem ví dụ về hộp thoại đồng ý mà người dùng nhìn thấy trên Google.

Trước khi phát hành một mã truy cập cho ứng dụng của bạn, bạn cần phải có một phiên hoạt động hiện có và đang hoạt động của Google để nhắc người dùng đồng ý và ghi lại kết quả. Người dùng có thể được yêu cầu đăng nhập vào Tài khoản Google nếu phiên hiện tại chưa được thiết lập.

Nút đăng nhập khi chọn biểu tượng người dùng

Người dùng có thể đăng nhập vào Tài khoản Google trong một thẻ trình duyệt riêng hoặc thông qua trình duyệt hoặc hệ điều hành. Bạn nên thêm Đăng nhập bằng Google vào trang web của bạn để thiết lập một phiên hoạt động giữa Tài khoản Google và trình duyệt khi người dùng mở ứng dụng của bạn lần đầu tiên. Làm như vậy sẽ mang lại những lợi ích sau:

  • Giảm thiểu số lần người dùng phải đăng nhập, yêu cầu mã truy cập bắt đầu quy trình đăng nhập vào Tài khoản Google nếu phiên hoạt động chưa tồn tại.
  • Trực tiếp sử dụng trường Mã thông báo JWT thông tin xác thực email làm giá trị của thông số hint trong các đối tượng CodeClientConfig hoặc TokenClientConfig. Điều này đặc biệt hữu ích nếu nền tảng của bạn không duy trì hệ thống quản lý tài khoản người dùng.
  • Tra cứu và liên kết Tài khoản Google với tài khoản người dùng cục bộ hiện có trên nền tảng, giúp giảm thiểu các tài khoản trùng lặp trên nền tảng.
  • Khi một tài khoản cục bộ mới được tạo, các hộp thoại và luồng đăng ký của bạn có thể được tách biệt rõ ràng với hộp thoại và luồng xác thực người dùng, giúp giảm số bước cần thiết và cải thiện tỷ lệ bỏ qua.

Sau khi đăng nhập và trước khi mã thông báo truy cập được phát hành, người dùng phải đồng ý cho ứng dụng của bạn sử dụng phạm vi yêu cầu.

Sau khi có sự đồng ý, mã truy cập được trả về cùng với danh sách các phạm vi đã được người dùng phê duyệt hoặc bị từ chối.

Các quyền chi tiết cho phép người dùng phê duyệt hoặc từ chối từng phạm vi. Khi yêu cầu quyền truy cập vào nhiều phạm vi, mỗi phạm vi được cấp hoặc từ chối độc lập với các phạm vi khác. Dựa trên lựa chọn của người dùng, ứng dụng của bạn sẽ có chọn lọc các tính năng và chức năng phụ thuộc vào từng phạm vi.

Luồng ngầm ẩn

Thay thế Các tệp đối chiếu JavaScript dành cho tính năng Đăng nhập bằng Google bằng Dịch vụ nhận dạng của Google:

Đối tượng:

  • gapi.auth2.AuthorizeResponseTokenClient.TokenResponse
  • gapi.auth2.AuthResponseTokenClient.TokenResponse

Phương thức:

  • GoogleUser.hasGrantedScopes()google.accounts.oauth2.hasGrantedAllScopes()
  • GoogleUser.getGrantedScopes()google.accounts.oauth2.hasGrantedAllScopes()

Xoá Các tệp tham chiếu JavaScript của chương trình Đăng nhập bằng Google:

Phương thức:

  • GoogleUser.getAuthResponse()

Cập nhật ứng dụng web của bạn bằng hasGrantedAllScopes()hasGrantedAnyScope() bằng cách làm theo ví dụ quyền chi tiết này.

Luồng mã uỷ quyền

Cập nhật hoặc Thêm một điểm cuối mã uỷ quyền vào nền tảng phụ trợ của bạn bằng cách làm theo hướng dẫn trong phần xử lý mã xác thực.

Cập nhật nền tảng của bạn để làm theo các bước được mô tả trong hướng dẫn Sử dụng mô hình mã để xác thực yêu cầu và lấy mã truy cập cũng như mã làm mới.

Cập nhật nền tảng của bạn để bật hoặc tắt có chọn lọc các tính năng và chức năng dựa trên từng phạm vi mà người dùng đã phê duyệt bằng cách làm theo hướng dẫn về uỷ quyền gia tăngkiểm tra phạm vi truy cập của người dùng.

Ví dụ về luồng ngầm ẩn

Cách cũ

Thư viện ứng dụng GAPI

Ví dụ về Thư viện ứng dụng API của Google cho JavaScript chạy trong trình duyệt bằng cách sử dụng hộp thoại bật lên để người dùng đồng ý.

Mô-đun gapi.auth2 sẽ được tự động tải và sử dụng bởi gapi.client.init(), do đó sẽ bị ẩn.

<!DOCTYPE html>
  <html>
    <head>
      <script src="https://apis.google.com/js/api.js"></script>
      <script>
        function start() {
          gapi.client.init({
            'apiKey': 'YOUR_API_KEY',
            'clientId': 'YOUR_CLIENT_ID',
            'scope': 'https://www.googleapis.com/auth/cloud-translation',
            'discoveryDocs': ['https://www.googleapis.com/discovery/v1/apis/translate/v2/rest'],
          }).then(function() {
            // Execute an API request which is returned as a Promise.
            // The method name language.translations.list comes from the API discovery.
            return gapi.client.language.translations.list({
              q: 'hello world',
              source: 'en',
              target: 'de',
            });
          }).then(function(response) {
            console.log(response.result.data.translations[0].translatedText);
          }, function(reason) {
            console.log('Error: ' + reason.result.error.message);
          });
        };

        // Load the JavaScript client library and invoke start afterwards.
        gapi.load('client', start);
      </script>
    </head>
    <body>
      <div id="results"></div>
    </body>
  </html>

Thư viện ứng dụng JS

OAuth 2.0 cho ứng dụng web phía máy khách chạy trong trình duyệt bằng hộp thoại bật lên để người dùng đồng ý.

Mô-đun gapi.auth2 được tải theo cách thủ công.

<!DOCTYPE html>
<html><head></head><body>
<script>
  var GoogleAuth;
  var SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly';
  function handleClientLoad() {
    // Load the API's client and auth2 modules.
    // Call the initClient function after the modules load.
    gapi.load('client:auth2', initClient);
  }

  function initClient() {
    // In practice, your app can retrieve one or more discovery documents.
    var discoveryUrl = 'https://www.googleapis.com/discovery/v1/apis/drive/v3/rest';

    // Initialize the gapi.client object, which app uses to make API requests.
    // Get API key and client ID from API Console.
    // 'scope' field specifies space-delimited list of access scopes.
    gapi.client.init({
        'apiKey': 'YOUR_API_KEY',
        'clientId': 'YOUR_CLIENT_ID',
        'discoveryDocs': [discoveryUrl],
        'scope': SCOPE
    }).then(function () {
      GoogleAuth = gapi.auth2.getAuthInstance();

      // Listen for sign-in state changes.
      GoogleAuth.isSignedIn.listen(updateSigninStatus);

      // Handle initial sign-in state. (Determine if user is already signed in.)
      var user = GoogleAuth.currentUser.get();
      setSigninStatus();

      // Call handleAuthClick function when user clicks on
      //      "Sign In/Authorize" button.
      $('#sign-in-or-out-button').click(function() {
        handleAuthClick();
      });
      $('#revoke-access-button').click(function() {
        revokeAccess();
      });
    });
  }

  function handleAuthClick() {
    if (GoogleAuth.isSignedIn.get()) {
      // User is authorized and has clicked "Sign out" button.
      GoogleAuth.signOut();
    } else {
      // User is not signed in. Start Google auth flow.
      GoogleAuth.signIn();
    }
  }

  function revokeAccess() {
    GoogleAuth.disconnect();
  }

  function setSigninStatus() {
    var user = GoogleAuth.currentUser.get();
    var isAuthorized = user.hasGrantedScopes(SCOPE);
    if (isAuthorized) {
      $('#sign-in-or-out-button').html('Sign out');
      $('#revoke-access-button').css('display', 'inline-block');
      $('#auth-status').html('You are currently signed in and have granted ' +
          'access to this app.');
    } else {
      $('#sign-in-or-out-button').html('Sign In/Authorize');
      $('#revoke-access-button').css('display', 'none');
      $('#auth-status').html('You have not authorized this app or you are ' +
          'signed out.');
    }
  }

  function updateSigninStatus() {
    setSigninStatus();
  }
</script>

<button id="sign-in-or-out-button"
        style="margin-left: 25px">Sign In/Authorize</button>
<button id="revoke-access-button"
        style="display: none; margin-left: 25px">Revoke access</button>

<div id="auth-status" style="display: inline; padding-left: 25px"></div><hr>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.3/jquery.min.js"></script>
<script async defer src="https://apis.google.com/js/api.js"
        onload="this.onload=function(){};handleClientLoad()"
        onreadystatechange="if (this.readyState === 'complete') this.onload()">
</script>
</body></html>

Điểm cuối OAuth 2.0

OAuth 2.0 cho ứng dụng web phía máy khách chạy trong trình duyệt bằng lệnh chuyển hướng đến Google để người dùng đồng ý.

Ví dụ này cho thấy lệnh gọi trực tiếp tới các điểm cuối OAuth 2.0 của Google từ trình duyệt của người dùng và không sử dụng mô-đun gapi.auth2 hoặc thư viện JavaScript.

<!DOCTYPE html>
<html><head></head><body>
<script>
  var YOUR_CLIENT_ID = 'REPLACE_THIS_VALUE';
  var YOUR_REDIRECT_URI = 'REPLACE_THIS_VALUE';
  var fragmentString = location.hash.substring(1);

  // Parse query string to see if page request is coming from OAuth 2.0 server.
  var params = {};
  var regex = /([^&=]+)=([^&]*)/g, m;
  while (m = regex.exec(fragmentString)) {
    params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
  }
  if (Object.keys(params).length > 0) {
    localStorage.setItem('oauth2-test-params', JSON.stringify(params) );
    if (params['state'] && params['state'] == 'try_sample_request') {
      trySampleRequest();
    }
  }

  // If there's an access token, try an API request.
  // Otherwise, start OAuth 2.0 flow.
  function trySampleRequest() {
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    if (params && params['access_token']) {
      var xhr = new XMLHttpRequest();
      xhr.open('GET',
          'https://www.googleapis.com/drive/v3/about?fields=user&' +
          'access_token=' + params['access_token']);
      xhr.onreadystatechange = function (e) {
        if (xhr.readyState === 4 && xhr.status === 200) {
          console.log(xhr.response);
        } else if (xhr.readyState === 4 && xhr.status === 401) {
          // Token invalid, so prompt for user permission.
          oauth2SignIn();
        }
      };
      xhr.send(null);
    } else {
      oauth2SignIn();
    }
  }

  /*
   * Create form to request access token from Google's OAuth 2.0 server.
   */
  function oauth2SignIn() {
    // Google's OAuth 2.0 endpoint for requesting an access token
    var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

    // Create element to open OAuth 2.0 endpoint in new window.
    var form = document.createElement('form');
    form.setAttribute('method', 'GET'); // Send as a GET request.
    form.setAttribute('action', oauth2Endpoint);

    // Parameters to pass to OAuth 2.0 endpoint.
    var params = {'client_id': YOUR_CLIENT_ID,
                  'redirect_uri': YOUR_REDIRECT_URI,
                  'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
                  'state': 'try_sample_request',
                  'include_granted_scopes': 'true',
                  'response_type': 'token'};

    // Add form parameters as hidden input values.
    for (var p in params) {
      var input = document.createElement('input');
      input.setAttribute('type', 'hidden');
      input.setAttribute('name', p);
      input.setAttribute('value', params[p]);
      form.appendChild(input);
    }

    // Add form to page and submit it to open the OAuth 2.0 endpoint.
    document.body.appendChild(form);
    form.submit();
  }
</script>

<button onclick="trySampleRequest();">Try sample request</button>
</body></html>

Cách mới

Chỉ dùng GPS

Ví dụ này chỉ cho thấy thư viện JavaScript Dịch vụ nhận dạng của Google sử dụng mô hình mã thông báo và hộp thoại bật lên để người dùng đồng ý. Công cụ này được cung cấp để minh hoạ số bước tối thiểu cần thiết để định cấu hình ứng dụng, yêu cầu và lấy mã truy cập, cũng như gọi API của Google.

<!DOCTYPE html>
<html>
  <head>
    <script src="https://accounts.google.com/gsi/client" onload="initClient()" async defer></script>
  </head>
  <body>
    <script>
      var client;
      var access_token;

      function initClient() {
        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: (tokenResponse) => {
            access_token = tokenResponse.access_token;
          },
        });
      }
      function getToken() {
        client.requestAccessToken();
      }
      function revokeToken() {
        google.accounts.oauth2.revoke(access_token, () => {console.log('access token revoked')});
      }
      function loadCalendar() {
        var xhr = new XMLHttpRequest();
        xhr.open('GET', 'https://www.googleapis.com/calendar/v3/calendars/primary/events');
        xhr.setRequestHeader('Authorization', 'Bearer ' + access_token);
        xhr.send();
      }
    </script>
    <h1>Google Identity Services Authorization Token model</h1>
    <button onclick="getToken();">Get access token</button><br><br>
    <button onclick="loadCalendar();">Load Calendar</button><br><br>
    <button onclick="revokeToken();">Revoke token</button>
  </body>
</html>

GAPI không đồng bộ/chờ

Ví dụ này cho biết cách thêm thư viện Dịch vụ nhận dạng của Google bằng cách sử dụng mô hình mã thông báo, xóa mô-đun gapi.auth2 và gọi một API bằng cách sử dụng Thư viện ứng dụng API Google cho JavaScript.

Lời hứa, không đồng bộ và đang chờ được dùng để thực thi thứ tự tải thư viện cũng như để bắt và thử lại các lỗi uỷ quyền. Lệnh gọi API chỉ được thực hiện sau khi có mã truy cập hợp lệ.

Người dùng dự kiến sẽ nhấn nút "Hiển thị lịch" khi mã truy cập bị thiếu khi trang được tải lần đầu tiên hoặc sau đó khi mã truy cập đã hết hạn.

<!DOCTYPE html>
<html>
<head></head>
<body>
  <h1>GAPI with GIS async/await</h1>
  <button id="showEventsBtn" onclick="showEvents();">Show Calendar</button><br><br>
  <button id="revokeBtn" onclick="revokeToken();">Revoke access token</button>

  <script>

    const gapiLoadPromise = new Promise((resolve, reject) => {
      gapiLoadOkay = resolve;
      gapiLoadFail = reject;
    });
    const gisLoadPromise = new Promise((resolve, reject) => {
      gisLoadOkay = resolve;
      gisLoadFail = reject;
    });

    var tokenClient;

    (async () => {
      document.getElementById("showEventsBtn").style.visibility="hidden";
      document.getElementById("revokeBtn").style.visibility="hidden";

      // First, load and initialize the gapi.client
      await gapiLoadPromise;
      await new Promise((resolve, reject) => {
        // NOTE: the 'auth2' module is no longer loaded.
        gapi.load('client', {callback: resolve, onerror: reject});
      });
      await gapi.client.init({
        // NOTE: OAuth2 'scope' and 'client_id' parameters have moved to initTokenClient().
      })
      .then(function() {  // Load the Calendar API discovery document.
        gapi.client.load('https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest');
      });

      // Now load the GIS client
      await gisLoadPromise;
      await new Promise((resolve, reject) => {
        try {
          tokenClient = google.accounts.oauth2.initTokenClient({
              client_id: 'YOUR_CLIENT_ID',
              scope: 'https://www.googleapis.com/auth/calendar.readonly',
              prompt: 'consent',
              callback: '',  // defined at request time in await/promise scope.
          });
          resolve();
        } catch (err) {
          reject(err);
        }
      });

      document.getElementById("showEventsBtn").style.visibility="visible";
      document.getElementById("revokeBtn").style.visibility="visible";
    })();

    async function getToken(err) {

      if (err.result.error.code == 401 || (err.result.error.code == 403) &&
          (err.result.error.status == "PERMISSION_DENIED")) {

        // The access token is missing, invalid, or expired, prompt for user consent to obtain one.
        await new Promise((resolve, reject) => {
          try {
            // Settle this promise in the response callback for requestAccessToken()
            tokenClient.callback = (resp) => {
              if (resp.error !== undefined) {
                reject(resp);
              }
              // GIS has automatically updated gapi.client with the newly issued access token.
              console.log('gapi.client access token: ' + JSON.stringify(gapi.client.getToken()));
              resolve(resp);
            };
            tokenClient.requestAccessToken();
          } catch (err) {
            console.log(err)
          }
        });
      } else {
        // Errors unrelated to authorization: server errors, exceeding quota, bad requests, and so on.
        throw new Error(err);
      }
    }

    function showEvents() {

      // Try to fetch a list of Calendar events. If a valid access token is needed,
      // prompt to obtain one and then retry the original request.
      gapi.client.calendar.events.list({ 'calendarId': 'primary' })
      .then(calendarAPIResponse => console.log(JSON.stringify(calendarAPIResponse)))
      .catch(err  => getToken(err))  // for authorization errors obtain an access token
      .then(retry => gapi.client.calendar.events.list({ 'calendarId': 'primary' }))
      .then(calendarAPIResponse => console.log(JSON.stringify(calendarAPIResponse)))
      .catch(err  => console.log(err));   // cancelled by user, timeout, etc.
    }

    function revokeToken() {
      let cred = gapi.client.getToken();
      if (cred !== null) {
        google.accounts.oauth2.revoke(cred.access_token, () => {console.log('Revoked: ' + cred.access_token)});
        gapi.client.setToken('');
      }
    }

  </script>

  <script async defer src="https://apis.google.com/js/api.js" onload="gapiLoadOkay()" onerror="gapiLoadFail(event)"></script>
  <script async defer src="https://accounts.google.com/gsi/client" onload="gisLoadOkay()" onerror="gisLoadFail(event)"></script>

</body>
</html>

Lệnh gọi lại GAPI

Ví dụ này cho biết cách thêm thư viện Dịch vụ nhận dạng của Google bằng cách sử dụng mô hình mã thông báo, xóa mô-đun gapi.auth2 và gọi một API bằng cách sử dụng Thư viện ứng dụng API Google cho JavaScript.

Các biến được dùng để thực thi thứ tự tải thư viện. Các lệnh gọi GAPI được thực hiện từ bên trong lệnh gọi lại sau khi trả về một mã truy cập hợp lệ.

Người dùng cần phải nhấn nút Hiển thị lịch khi trang được tải lần đầu tiên và nhấn lại khi họ muốn làm mới thông tin Lịch của mình.

<!DOCTYPE html>
<html>
<head>
  <script async defer src="https://apis.google.com/js/api.js" onload="gapiLoad()"></script>
  <script async defer src="https://accounts.google.com/gsi/client" onload="gisInit()"></script>
</head>
<body>
  <h1>GAPI with GIS callbacks</h1>
  <button id="showEventsBtn" onclick="showEvents();">Show Calendar</button><br><br>
  <button id="revokeBtn" onclick="revokeToken();">Revoke access token</button>
  <script>
    let tokenClient;
    let gapiInited;
    let gisInited;

    document.getElementById("showEventsBtn").style.visibility="hidden";
    document.getElementById("revokeBtn").style.visibility="hidden";

    function checkBeforeStart() {
       if (gapiInited && gisInited){
          // Start only when both gapi and gis are initialized.
          document.getElementById("showEventsBtn").style.visibility="visible";
          document.getElementById("revokeBtn").style.visibility="visible";
       }
    }

    function gapiInit() {
      gapi.client.init({
        // NOTE: OAuth2 'scope' and 'client_id' parameters have moved to initTokenClient().
      })
      .then(function() {  // Load the Calendar API discovery document.
        gapi.client.load('https://www.googleapis.com/discovery/v1/apis/calendar/v3/rest');
        gapiInited = true;
        checkBeforeStart();
      });
    }

    function gapiLoad() {
        gapi.load('client', gapiInit)
    }

    function gisInit() {
     tokenClient = google.accounts.oauth2.initTokenClient({
                client_id: 'YOUR_CLIENT_ID',
                scope: 'https://www.googleapis.com/auth/calendar.readonly',
                callback: '',  // defined at request time
            });
      gisInited = true;
      checkBeforeStart();
    }

    function showEvents() {

      tokenClient.callback = (resp) => {
        if (resp.error !== undefined) {
          throw(resp);
        }
        // GIS has automatically updated gapi.client with the newly issued access token.
        console.log('gapi.client access token: ' + JSON.stringify(gapi.client.getToken()));

        gapi.client.calendar.events.list({ 'calendarId': 'primary' })
        .then(calendarAPIResponse => console.log(JSON.stringify(calendarAPIResponse)))
        .catch(err => console.log(err));

        document.getElementById("showEventsBtn").innerText = "Refresh Calendar";
      }

      // Conditionally ask users to select the Google Account they'd like to use,
      // and explicitly obtain their consent to fetch their Calendar.
      // NOTE: To request an access token a user gesture is necessary.
      if (gapi.client.getToken() === null) {
        // Prompt the user to select a Google Account and asked for consent to share their data
        // when establishing a new session.
        tokenClient.requestAccessToken({prompt: 'consent'});
      } else {
        // Skip display of account chooser and consent dialog for an existing session.
        tokenClient.requestAccessToken({prompt: ''});
      }
    }

    function revokeToken() {
      let cred = gapi.client.getToken();
      if (cred !== null) {
        google.accounts.oauth2.revoke(cred.access_token, () => {console.log('Revoked: ' + cred.access_token)});
        gapi.client.setToken('');
        document.getElementById("showEventsBtn").innerText = "Show Calendar";
      }
    }
  </script>
</body>
</html>

Ví dụ về quy trình mã uỷ quyền

Trải nghiệm người dùng bật lên của thư viện Dịch vụ nhận dạng Google có thể sử dụng lệnh chuyển hướng URL để trực tiếp trả về mã uỷ quyền cho điểm cuối mã thông báo phụ trợ của bạn hoặc trình xử lý gọi lại JavaScript chạy trong trình duyệt của người dùng để phản hồi proxy trong nền tảng của bạn. Trong cả hai trường hợp, nền tảng phụ trợ của bạn sẽ hoàn tất quy trình OAuth 2.0 để có được mã truy cập và làm mới hợp lệ.

Cách cũ

Ứng dụng web phía máy chủ

Đăng nhập bằng Google cho ứng dụng phía máy chủ chạy trên nền tảng phụ trợ bằng cách sử dụng chuyển hướng đến Google để lấy sự đồng ý của người dùng.

<!DOCTYPE html>
<html>
  <head>
    <script src="//ajax.googleapis.com/ajax/libs/jquery/1.8.2/jquery.min.js"></script>
    <script src="https://apis.google.com/js/client:platform.js?onload=start" async defer></script>
    <script>
      function start() {
        gapi.load('auth2', function() {
          auth2 = gapi.auth2.init({
            client_id: 'YOUR_CLIENT_ID',
            api_key: 'YOUR_API_KEY',
            discovery_docs: ['https://www.googleapis.com/discovery/v1/apis/translate/v2/rest'],
            // Scopes to request in addition to 'profile' and 'email'
            scope: 'https://www.googleapis.com/auth/cloud-translation',
          });
        });
      }
      function signInCallback(authResult) {
        if (authResult['code']) {
          console.log("sending AJAX request");
          // Send authorization code obtained from Google to backend platform
          $.ajax({
            type: 'POST',
            url: 'YOUR_AUTHORIZATION_CODE_ENDPOINT_URL',
            // Always include an X-Requested-With header to protect against CSRF attacks.
            headers: {
              'X-Requested-With': 'XMLHttpRequest'
            },
            contentType: 'application/octet-stream; charset=utf-8',
            success: function(result) {
              console.log(result);
            },
            processData: false,
            data: authResult['code']
          });
        } else {
          console.log('error: failed to obtain authorization code')
        }
      }
    </script>
  </head>
  <body>
    <button id="signinButton">Sign In With Google</button>
    <script>
      $('#signinButton').click(function() {
        // Obtain an authorization code from Google
        auth2.grantOfflineAccess().then(signInCallback);
      });
    </script>
  </body>
</html>

HTTP/REST sử dụng lệnh chuyển hướng

Sử dụng OAuth 2.0 cho ứng dụng máy chủ web để gửi mã uỷ quyền từ trình duyệt của người dùng đến nền tảng phụ trợ. Đã xử lý sự đồng ý của người dùng bằng cách chuyển hướng trình duyệt của người dùng đến Google.

/\*
 \* Create form to request access token from Google's OAuth 2.0 server.
 \*/
function oauthSignIn() {
  // Google's OAuth 2.0 endpoint for requesting an access token
  var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';
  // Create &lt;form> element to submit parameters to OAuth 2.0 endpoint.
  var form = document.createElement('form');
  form.setAttribute('method', 'GET'); // Send as a GET request.
  form.setAttribute('action', oauth2Endpoint);
  // Parameters to pass to OAuth 2.0 endpoint.
  var params = {'client\_id': 'YOUR_CLIENT_ID',
                'redirect\_uri': 'YOUR_AUTHORIZATION_CODE_ENDPOINT_URL',
                'response\_type': 'token',
                'scope': 'https://www.googleapis.com/auth/drive.metadata.readonly',
                'include\_granted\_scopes': 'true',
                'state': 'pass-through value'};
  // Add form parameters as hidden input values.
  for (var p in params) {
    var input = document.createElement('input');
    input.setAttribute('type', 'hidden');
    input.setAttribute('name', p);
    input.setAttribute('value', params[p]);
    form.appendChild(input);
  }

  // Add form to page and submit it to open the OAuth 2.0 endpoint.
  document.body.appendChild(form);
  form.submit();
}

Cách mới

Trải nghiệm người dùng cửa sổ bật lên GIS

Ví dụ này chỉ cho thấy thư viện JavaScript Dịch vụ danh tính của Google sử dụng mô hình mã uỷ quyền hộp thoại bật lên để người dùng đồng ý và trình xử lý gọi lại nhận mã uỷ quyền từ Google. Bài viết này được cung cấp để minh họa số bước tối thiểu cần thiết để định cấu hình ứng dụng, lấy sự đồng ý và gửi mã uỷ quyền đến nền tảng phụ trợ của bạn.

<!DOCTYPE html>
<html>
  <head>
    <script src="https://accounts.google.com/gsi/client" onload="initClient()" async defer></script>
  </head>
  <body>
    <script>
      var client;
      function initClient() {
        client = google.accounts.oauth2.initCodeClient({
          client_id: 'YOUR_CLIENT_ID',
          scope: 'https://www.googleapis.com/auth/calendar.readonly',
          ux_mode: 'popup',
          callback: (response) => {
            var code_receiver_uri = 'YOUR_AUTHORIZATION_CODE_ENDPOINT_URI',
            // Send auth code to your backend platform
            const xhr = new XMLHttpRequest();
            xhr.open('POST', code_receiver_uri, true);
            xhr.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
            xhr.setRequestHeader('X-Requested-With', 'XMLHttpRequest');
            xhr.onload = function() {
              console.log('Signed in as: ' + xhr.responseText);
            };
            xhr.send('code=' + response.code);
            // After receipt, the code is exchanged for an access token and
            // refresh token, and the platform then updates this web app
            // running in user's browser with the requested calendar info.
          },
        });
      }
      function getAuthCode() {
        // Request authorization code and obtain user consent
          client.requestCode();
      }
    </script>
    <button onclick="getAuthCode();">Load Your Calendar</button>
  </body>
</html>

Trải nghiệm người dùng chuyển hướng trên Hệ thống thông tin địa lý (GGA)

Mô hình mã uỷ quyền hỗ trợ chế độ cửa sổ bật lên và chuyển hướng trải nghiệm người dùng để gửi mã uỷ quyền cho mỗi người dùng đến điểm cuối do nền tảng của bạn lưu trữ. Chế độ trải nghiệm chuyển hướng xuất hiện tại đây:

<!DOCTYPE html>
<html>
  <head>
    <script src="https://accounts.google.com/gsi/client" onload="initClient()" async defer></script>
  </head>
  <body>
    <script>
      var client;
      function initClient() {
        client = google.accounts.oauth2.initCodeClient({
          client_id: 'YOUR_CLIENT_ID',
          scope: 'https://www.googleapis.com/auth/calendar.readonly \
                  https://www.googleapis.com/auth/photoslibrary.readonly',
          ux_mode: 'redirect',
          redirect_uri: 'YOUR_AUTHORIZATION_CODE_ENDPOINT_URI'
        });
      }
      // Request an access token
      function getAuthCode() {
        // Request authorization code and obtain user consent
          client.requestCode();
      }
    </script>
    <button onclick="getAuthCode();">Load Your Calendar</button>
  </body>
</html>

Thư viện JavaScript

Dịch vụ nhận dạng của Google là một thư viện JavaScript duy nhất dùng để xác thực và uỷ quyền người dùng hợp nhất và thay thế các tính năng cũng như chức năng có trong nhiều thư viện và mô-đun khác nhau:

Việc cần làm khi di chuyển sang Dịch vụ nhận dạng:

Thư viện JS hiện có Thư viện JS mới Ghi chú
apis.google.com/js/api.js accounts.google.com/gsi/client Thêm thư viện mới và làm theo luồng ngầm ẩn.
apis.google.com/js/client.js accounts.google.com/gsi/client Thêm thư viện mới và quy trình mã uỷ quyền.

Tài liệu tham khảo nhanh về thư viện

So sánh đối tượng và phương thức giữa thư viện ứng dụng JavaScript cũ Đăng nhập bằng Google, thư viện Mới Dịch vụ nhận dạng của GoogleGhi chú có thêm thông tin và hành động cần thực hiện trong quá trình di chuyển.

Mới Ghi chú
GoogleAuth và các phương thức liên kết:
GoogleAuth.AttachClickHandler() Xóa
GoogleAuth.currentUser.get() Xóa
GoogleAuth.currentUser.listen() Xóa
GoogleAuth.Disconnect() google.accounts.OAuth2.revoke Thay thế phiên bản cũ bằng phiên bản mới. Việc thu hồi cũng có thể xảy ra tại https://myaccount.google.com/permissions
GoogleAuth.grantOfflineAccess() Xoá, hãy làm theo quy trình mã uỷ quyền.
GoogleAuth.isSignedIn.get() Xóa
GoogleAuth.isSignedIn.listen() Xóa
GoogleAuth.signIn() Xóa
GoogleAuth.signOut() Xóa
GoogleAuth.then() Xóa
Đối tượng GoogleUser và các phương thức liên kết:
GoogleUser.Disconnect() google.accounts.id.revoke Thay thế phiên bản cũ bằng phiên bản mới. Việc thu hồi cũng có thể xảy ra tại https://myaccount.google.com/permissions
GoogleUser.getAuthResponse() requestCode() hoặc requestAccessToken() Thay thế mã cũ bằng mã mới
GoogleUser.getBasicProfile() Xóa. Thay vào đó, hãy sử dụng Mã thông báo mã nhận dạng, xem bài viết Di chuyển từ tính năng Đăng nhập bằng Google.
GoogleUser.getGrantedScopes() hasGrantedAnyScope() Thay thế mã cũ bằng mã mới
GoogleUser.getHostedDomain() Xóa
GoogleUser.getId() Xóa
GoogleUser.grantOfflineAccess() Xoá, hãy làm theo quy trình mã uỷ quyền.
GoogleUser.grant() Xóa
GoogleUser.hasGrantedScopes() hasGrantedAnyScope() Thay thế mã cũ bằng mã mới
GoogleUser.isSignedIn() Xóa
GoogleUser.reloadAuthResponse() requestAccessToken() Hãy xoá mã cũ, gọi lệnh mới để thay thế mã truy cập đã hết hạn hoặc bị thu hồi.
gapi.auth2 và các phương thức liên kết:
gapi.auth2.uỷ quyền đối tượng Cấu hình tokenClientConfig hoặc CodeClientConfig Thay thế mã cũ bằng mã mới
gapi.auth2.uỷ quyền đối tượng Xóa
Đối tượng gapi.auth2.AuthResponse Xóa
gapi.auth2.authorized() requestCode() hoặc requestAccessToken() Thay thế mã cũ bằng mã mới
gapi.auth2.ClientConfig() tokenClientConfig hoặc CodeClientConfig Thay thế mã cũ bằng mã mới
gapi.auth2.getAuthInstance() Xóa
gapi.auth2.init() initTokenClient() hoặc initCodeClient() Thay thế mã cũ bằng mã mới
Đối tượng gapi.auth2.OfflineAccessOptions Xóa
Đối tượng gapi.auth2.SignInOptions Xóa
gapi.signin2 và các phương thức liên kết:
gapi.signin2.render() Xóa. Tải HTML DOM của phần tử g_id_signin hoặc lệnh gọi JS đến google.accounts.id.renderButton sẽ kích hoạt quá trình đăng nhập của người dùng vào một Tài khoản Google.

Thông tin xác thực mẫu

Bằng chứng xác thực hiện có

Thư viện nền tảng Đăng nhập bằng Google, Thư viện ứng dụng API cho Google cho JavaScript hoặc lệnh gọi trực tiếp đến các điểm cuối Xác thực của Google 2.0 trả về cả mã thông báo truy cập OAuth 2.0 và Mã thông báo mã nhận dạng Connect Connect trong một phản hồi.

Ví dụ về phản hồi chứa cả access_tokenid_token:

  {
    "token_type": "Bearer",
    "access_token": "ya29.A0ARrdaM-SmArZaCIh68qXsZSzyeU-8mxhQERHrP2EXtxpUuZ-3oW8IW7a6D2J6lRnZrRj8S6-ZcIl5XVEqnqxq5fuMeDDH_6MZgQ5dgP7moY-yTiKR5kdPm-LkuPM-mOtUsylWPd1wpRmvw_AGOZ1UUCa6UD5Hg",
    "scope": "https://www.googleapis.com/auth/calendar.readonly",
    "login_hint": "AJDLj6I2d1RH77cgpe__DdEree1zxHjZJr4Q7yOisoumTZUmo5W2ZmVFHyAomUYzLkrluG-hqt4RnNxrPhArd5y6p8kzO0t8xIfMAe6yhztt6v2E-_Bb4Ec3GLFKikHSXNh5bI-gPrsI",
    "expires_in": 3599,
    "id_token": "eyJhbGciOiJSUzI1NiIsImtpZCI6IjkzNDFhYmM0MDkyYjZmYzAzOGU0MDNjOTEwMjJkZDNlNDQ1MzliNTYiLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJhY2NvdW50cy5nb29nbGUuY29tIiwiYXpwIjoiNTM4MzQ0NjUzMjU1LTc1OGM1aDVpc2M0NXZnazI3ZDhoOGRlYWJvdnBnNnRvLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwiYXVkIjoiNTM4MzQ0NjUzMjU1LTc1OGM1aDVpc2M0NXZnazI3ZDhoOGRlYWJvdnBnNnRvLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwic3ViIjoiMTE3NzI2NDMxNjUxOTQzNjk4NjAwIiwiaGQiOiJnb29nbGUuY29tIiwiZW1haWwiOiJkYWJyaWFuQGdvb2dsZS5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXRfaGFzaCI6IkJBSW55TjN2MS1ZejNLQnJUMVo0ckEiLCJuYW1lIjoiQnJpYW4gRGF1Z2hlcnR5IiwicGljdHVyZSI6Imh0dHBzOi8vbGgzLmdvb2dsZXVzZXJjb250ZW50LmNvbS9hLS9BT2gxNEdnenAyTXNGRGZvbVdMX3VDemRYUWNzeVM3ZGtxTE5ybk90S0QzVXNRPXM5Ni1jIiwiZ2l2ZW5fbmFtZSI6IkJyaWFuIiwiZmFtaWx5X25hbWUiOiJEYXVnaGVydHkiLCJsb2NhbGUiOiJlbiIsImlhdCI6MTYzODk5MTYzOCwiZXhwIjoxNjM4OTk1MjM4LCJqdGkiOiI5YmRkZjE1YWFiNzE2ZDhjYmJmNDYwMmM1YWM3YzViN2VhMDQ5OTA5In0.K3EA-3Adw5HA7O8nJVCsX1HmGWxWzYk3P7ViVBb4H4BoT2-HIgxKlx1mi6jSxIUJGEekjw9MC-nL1B9Asgv1vXTMgoGaNna0UoEHYitySI23E5jaMkExkTSLtxI-ih2tJrA2ggfA9Ekj-JFiMc6MuJnwcfBTlsYWRcZOYVw3QpdTZ_VYfhUu-yERAElZCjaAyEXLtVQegRe-ymScra3r9S92TA33ylMb3WDTlfmDpWL0CDdDzby2asXYpl6GQ7SdSj64s49Yw6mdGELZn5WoJqG7Zr2KwIGXJuSxEo-wGbzxNK-mKAiABcFpYP4KHPEUgYyz3n9Vqn2Tfrgp-g65BQ",
    "session_state": {
      "extraQueryParams": {
        "authuser": "0"
      }
    },
    "first_issued_at": 1638991637982,
    "expires_at": 1638995236982,
    "idpId": "google"
  }

Thông tin xác thực Dịch vụ nhận dạng của Google

Thư viện Dịch vụ nhận dạng của Google trả về:

  • mã truy cập khi được dùng để uỷ quyền:
  {
    "access_token": "ya29.A0ARrdaM_LWSO-uckLj7IJVNSfnUityT0Xj-UCCrGxFQdxmLiWuAosnAKMVQ2Z0LLqeZdeJii3TgULp6hR_PJxnInBOl8UoUwWoqsrGQ7-swxgy97E8_hnzfhrOWyQBmH6zs0_sUCzwzhEr_FAVqf92sZZHphr0g",
    "token_type": "Bearer",
    "expires_in": 3599,
    "scope": "https://www.googleapis.com/auth/calendar.readonly"
  }
  • hoặc một mã thông báo mã nhận dạng khi dùng để xác thực:
  {
  "clientId": "538344653255-758c5h5isc45vgk27d8h8deabovpg6to.apps.googleusercontent.com",
  "credential": "eyJhbGciOiJSUzI1NiIsImtpZCI6ImMxODkyZWI0OWQ3ZWY5YWRmOGIyZTE0YzA1Y2EwZDAzMjcxNGEyMzciLCJ0eXAiOiJKV1QifQ.eyJpc3MiOiJodHRwczovL2FjY291bnRzLmdvb2dsZS5jb20iLCJuYmYiOjE2MzkxNTcyNjQsImF1ZCI6IjUzODM0NDY1MzI1NS03NThjNWg1aXNjNDV2Z2syN2Q4aDhkZWFib3ZwZzZ0by5hcHBzLmdvb2dsZXVzZXJjb250ZW50LmNvbSIsInN1YiI6IjExNzcyNjQzMTY1MTk0MzY5ODYwMCIsIm5vbmNlIjoiZm9vYmFyIiwiaGQiOiJnb29nbGUuY29tIiwiZW1haWwiOiJkYWJyaWFuQGdvb2dsZS5jb20iLCJlbWFpbF92ZXJpZmllZCI6dHJ1ZSwiYXpwIjoiNTM4MzQ0NjUzMjU1LTc1OGM1aDVpc2M0NXZnazI3ZDhoOGRlYWJvdnBnNnRvLmFwcHMuZ29vZ2xldXNlcmNvbnRlbnQuY29tIiwibmFtZSI6IkJyaWFuIERhdWdoZXJ0eSIsInBpY3R1cmUiOiJodHRwczovL2xoMy5nb29nbGV1c2VyY29udGVudC5jb20vYS0vQU9oMTRHZ3pwMk1zRkRmb21XTF91Q3pkWFFjc3lTN2RrcUxOcm5PdEtEM1VzUT1zOTYtYyIsImdpdmVuX25hbWUiOiJCcmlhbiIsImZhbWlseV9uYW1lIjoiRGF1Z2hlcnR5IiwiaWF0IjoxNjM5MTU3NTY0LCJleHAiOjE2MzkxNjExNjQsImp0aSI6IjRiOTVkYjAyZjU4NDczMmUxZGJkOTY2NWJiMWYzY2VhYzgyMmI0NjUifQ.Cr-AgMsLFeLurnqyGpw0hSomjOCU4S3cU669Hyi4VsbqnAV11zc_z73o6ahe9Nqc26kPVCNRGSqYrDZPfRyTnV6g1PIgc4Zvl-JBuy6O9HhClAK1HhMwh1FpgeYwXqrng1tifmuotuLQnZAiQJM73Gl-J_6s86Buo_1AIx5YAKCucYDUYYdXBIHLxrbALsA5W6pZCqqkMbqpTWteix-G5Q5T8LNsfqIu_uMBUGceqZWFJALhS9ieaDqoxhIqpx_89QAr1YlGu_UO6R6FYl0wDT-nzjyeF5tonSs3FHN0iNIiR3AMOHZu7KUwZaUdHg4eYkU-sQ01QNY_11keHROCRQ",
  "select_by": "user"
  }

Phản hồi mã thông báo không hợp lệ

Ví dụ về phản hồi của Google khi cố gắng tạo một yêu cầu API bằng mã truy cập đã hết hạn, bị thu hồi hoặc không hợp lệ:

Tiêu đề phản hồi HTTP

  www-authenticate: Bearer realm="https://accounts.google.com/", error="invalid_token"

Nội dung phản hồi

  {
    "error": {
      "code": 401,
      "message": "Request had invalid authentication credentials. Expected OAuth 2 access token, login cookie or other valid authentication credential. See https://developers.google.com/identity/sign-in/web/devconsole-project.",
      "errors": [
        {
          "message": "Invalid Credentials",
          "domain": "global",
          "reason": "authError",
          "location": "Authorization",
          "locationType": "header"
        }
      ],
      "status": "UNAUTHENTICATED"
    }
  }