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

Tổng quan

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

Hướng dẫn này cung cấp cho bạn thông tin để 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.

Khi 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 còn dùng nữa, cũng như các phương thức và đối tượng của mô-đun đó, thay thế bằng các dịch vụ tương đương của Dịch vụ nhận dạng.

Để xem nội dung mô tả về những thay đổi với thư viện JavaScript của Dịch vụ danh tính, hãy đọc nội dung tổng quancách hoạt động của quy trình uỷ quyền người dùng để xem 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 cho quy trình đăng ký và đăng nhập của người dùng, hãy xem phần Di chuyển từ tính năng đăng nhập bằng Google.

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

Có 2 quy trình uỷ quyền cho người dùng: mã ngầm ẩn và mã uỷ quyền.

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

Các chỉ báo mà ứng dụng web của bạn đang sử dụng luồng ngầm ẩn:

  • Ứng dụng web của bạn chỉ hoạt động dựa trên trình duyệt, không có nền tảng phụ trợ.
  • Người dùng phải có mặt để gọi API của Google, ứng dụng của bạn chỉ sử dụng mã 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.
  • Cách triển khai của bạn dựa trên OAuth 2.0 cho Ứng dụng web phía máy khách.
  • Ứng dụng của bạn dùng các mô-đun gapi.client hoặc gapi.auth2 có trong Thư viện ứng dụng Google API cho JavaScript.

Các dấu hiệu mà ứ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 của bạn thực thi cả trong trình duyệt của người dùng và trên nền tảng phụ trợ.

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

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

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

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

Chọn một quy trình uỷ quyền

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

Xem lại bài viết chọn một quy trình uỷ quyền để hiểu những điểm khác biệt chính và sự đánh đổi giữa 2 quy trình này.

Trong hầu hết các trường hợp, bạn nên sử dụng quy trình mã uỷ quyền vì quy trình này có mức độ bảo mật người dùng cao nhất. 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 bản 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 của họ, v.v.

Chọn một 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

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

Ví dụ về quy trình 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.

Quy trình mã uỷ quyền

Mã uỷ quyền cho mỗi người dùng do Google cấp sẽ được gửi đến nền tảng phụ trợ của bạn. Tại đây, mã này sẽ được đổi lấy mã truy cập và mã làm mới.

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

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

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 của 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í của mã bị ảnh hưởng và kiểm thử hành vi sau khi ngừng hoạt động.

Trong các ứng dụng lớn hoặc phức tạp, có thể khó tìm thấy tất cả các mã bị ảnh hưởng do việc ngừng sử dụng mô-đun gapi.auth2. Để ghi lại các hoạt động sử dụng hiện tại sắp không 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. (Không bắt buộc) Thêm dấu hai chấm, theo sau là một giá trị khoá để ghi vào bộ nhớ phiên. Sau khi đăng nhập và nhận được xem xét thông tin xác thực hoặc gửi nhật ký đã thu thập tới phần phụ trợ để phân tích sau này. Ví dụ: informational:showauth2use lưu nguồn gốc và URL vào khoá lưu trữ phiên hoạt động có tên là 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. Việc này giúp kiểm thử hành vi sau khi ngừng hoạt động trước ngày thực thi.

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

  • 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. Đồng thời ghi lại vào 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, trước tiên bạn nên đặt cookie này cục bộ trong quá trình phát triển và kiểm thử, trước khi sử dụng trong môi trường thực tế.

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

Mô-đun gapi.auth2 quản lý quy trình xác thực người dùng đối với hoạt độ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 đó bằng 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:

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

Xoá mọi phiên bản 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 trong Thư viện ứng dụng API của Google cho JavaScript và tận dụng tính năng tự động tạo các phương thức JS có thể gọi từ tài liệu khám phá, tạo lô nhiều lệnh gọi API và chức năng quản lý CORS.

Bánh quy

Việc cho phép người dùng không yêu cầu sử dụng cookie.

Hãy xem bài viết Di chuyển từ tính năng đăng nhập bằng Google để biết 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 cho các sản phẩm và dịch vụ khác của Google sử dụng cookie.

Thông tin xác thực

Dịch vụ nhận dạng của Google tách riêng hoạt động xác thực và uỷ quyền của người dùng thành hai hoạt động riêng biệt. Đồng thời, thông tin xác thực của người dùng cũng tách biệt: mã thông báo nhận dạng dùng để nhận dạng người dùng sẽ được trả về riêng biệt với mã truy cập dùng để uỷ quyền.

Để xem những thay đổi này, hãy xem ví dụ về thông tin đăng nhập.

Luồng ngầm

Tách biệt quá trình xác thực và uỷ quyền người dùng bằng cách xoá hoạt động xử lý hồ sơ người dùng khỏi các quy trình uỷ quyền.

Xoá các tham chiếu đến ứng dụng JavaScript sử dụng tính năng Đăng nhập bằng Google:

Phương thức

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

Quy trình mã uỷ quyền

Dịch vụ danh tính sẽ tách thông tin xác thực trong trình duyệt thành 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 nhận đượ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 các thư viện chạy trên một 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 Node.js của API Google.

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 cách sử dụng:

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

Xoá các tham chiếu đến ứng dụng JavaScript sử dụng tính năng Đăng nhập bằng Google:

Đố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

Hãy cập nhật ứng dụng web của bạn để khởi chạy một ứng dụng mã thông báo cho quy trình mã ngầm ẩn hoặc uỷ quyền.

Xoá các tham chiếu đến ứng dụng JavaScript sử dụng tính năng Đăng nhập bằng Google:

Đối tượng:

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

Phương thức:

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

Luồng ngầm

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

Thay thế tài liệu tham chiếu của ứng dụng JavaScript sử dụng 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.AuthorizeConfig cộng tác với TokenClientConfig

Phương thức:

  • gapi.auth2.init() cộng tác với google.accounts.oauth2.initTokenClient()

Các thông số:

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

Quy trình 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, theo ví dụ trong phần khởi động Ứng dụng mã.

Khi chuyển từ quy trình ngầm định sang quy trình mã uỷ quyền:

Xoá tài liệu tham chiếu đến ứng dụng JavaScript sử dụng tính năng Đăng nhập bằng Google

Đối tượng:

  • gapi.auth2.AuthorizeConfig

Phương thức:

  • gapi.auth2.init()

Các thông số:

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

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

Cử chỉ của người dùng (chẳng hạn như nhấp vào nút) sẽ tạo ra một yêu cầu dẫn đến việc mã truy cập được trả về trực tiếp cho trình duyệt của người dùng thông qua luồng ngầm ẩn, hoặc cho 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

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

Thay thế tài liệu tham khảo của ứng dụng JavaScript về tính năng Đă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() cộng tác với TokenClient.requestAccessToken()
  • GoogleUser.reloadAuthResponse() bằng TokenClient.requestAccessToken()

Thêm một đường liên kết hoặc nút để gọi requestAccessToken() nhằm bắt đầu quy trình 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 thành:

  • 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 để phân 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ã thông báo hiện có hết hạn hoặc bị thu hồi.

Khi xử lý nhiều phạm vi, bạn có thể phải thay đổi cấu trúc đối với cơ sở mã để chỉ yêu cầu quyền truy cập vào các phạm vi khi cần thay vì tất cả cùng một lúc. Đây được gọi là sự uỷ quyền gia tăng. Mỗi yêu cầu nên chứa ít phạm vi nhất có thể và lý tưởng nhất là một phạm vi. 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 để uỷ quyền gia tăng.

Khi mã truy cập hết hạn, mô-đun gapi.auth2 sẽ tự động nhận mã truy cập mới, hợp lệ cho ứng dụng web của bạn. Để cải thiện khả năng bảo mật cho người dùng, thư viện Google Identity Services không hỗ trợ quy trình làm mới mã thông báo tự động này. 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ã 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.

Quy trình mã uỷ quyền

Thêm một đường liên kết hoặc nút để gọi requestCode() để yêu cầu mã uỷ quyền từ Google. Để biết ví dụ, hãy xem bài viết Kích hoạt quy trình mã OAuth 2.0.

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

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

Thêm chế độ xử lý lỗi để phát hiện lệnh gọi API của 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, cũng như để yêu cầu một mã truy cập mới hợp lệ.

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

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

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

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

Bất cứ lúc nào chủ sở hữu Tài khoản Google cũng có thể thu hồi sự đồng ý đã đồng ý trước đó. Thao tác này sẽ làm mất hiệu lực của mã truy cập và mã làm mới hiện có. Việc thu hồi có thể được kích hoạt trên 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ế tài liệu tham khảo của ứng dụng JavaScript về tính năng Đăng nhập bằng Google: bằng Dịch vụ nhận dạng của Google:

Phương thức:

  • getAuthInstance().disconnect() cộng tác với google.accounts.oauth2.revoke()
  • GoogleUser.disconnect() cộng tác với 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à Google hiển thị cho người dùng.

Trước khi cấp mã truy cập cho ứng dụng của mình, bạn phải có một phiên hoạt động hiện có và đang hoạt động trên 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 có chưa được thiết lập.

Thông tin đăng nhập của 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 một trình duyệt hoặc hệ điều hành. Bạn nên thêm tính năng Đăng nhập bằng Google vào trang web của mình để thiết lập 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 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. Việc yêu cầu một mã truy cập sẽ bắt đầu quy trình đăng nhập vào Tài khoản Google nếu chưa có phiên hoạt động.
  • Sử dụng trực tiếp trường thông tin xác thực email của Mã thông báo mã nhận dạng JWT làm giá trị của tham số login_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 một tài khoản người dùng cục bộ hiện có trên nền tảng của bạn, giúp giảm thiểu các tài khoản trùng lặp trên nền tảng của bạn.
  • Khi một tài khoản mới trên máy được tạo, hộp thoại và quy trình đăng ký của bạn có thể được tách biệt rõ ràng với hộp thoại và quy trình xác thực người dùng, giúp giảm số bước bắt buộc và cải thiện tỷ lệ bỏ ngang.

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

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

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 sẽ được cấp hoặc bị từ chối một cách độ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ẽ bật các tính năng và chức năng tuỳ thuộc vào từng phạm vi.

Luồng ngầm

Thay thế tài liệu tham chiếu của ứng dụng JavaScript sử dụng 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.AuthorizeResponse cộng tác với TokenClient.TokenResponse
  • gapi.auth2.AuthResponse cộng tác với TokenClient.TokenResponse

Phương thức:

  • GoogleUser.hasGrantedScopes() bằng google.accounts.oauth2.hasGrantedAllScopes()
  • GoogleUser.getGrantedScopes() bằng google.accounts.oauth2.hasGrantedAllScopes()

Xoá tài liệu tham chiếu đến ứng dụng JavaScript sử dụng tính năng Đăng nhập bằng Google:

Phương thức:

  • GoogleUser.getAuthResponse()

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

Quy trình mã uỷ quyền

Cập nhật hoặc Thêm điểm cuối của mã uỷ quyền vào nền tảng phụ trợ 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ã thông báo làm mới.

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

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 sử dụng hộp thoại bật lên để lấy sự đồng ý của người dùng.

Mô-đun gapi.auth2 được gapi.client.init() tự động tải và sử dụng nên 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 dành cho Ứng dụng web phía máy khách chạy trong trình duyệt thông qua hộp thoại bật lên để yêu cầu 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 sử dụng lệnh chuyển hướng đến Google để xin người dùng đồng ý.

Ví dụ này cho thấy các lệnh gọi trực tiếp đến đ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ỉ hệ thống thông tin địa lý (GIS)

Ví dụ này chỉ cho thấy thư viện JavaScript của Dịch vụ Google Identity (sử dụng mô hình mã thông báo) và hộp thoại bật lên để lấy sự đồng ý của người dùng. Hướng dẫn này được đưa ra để minh hoạ số bước tối thiểu cần thực hiện để định cấu hình một ứng dụng, yêu cầu và nhận mã truy cập cũng như để gọi một 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 async/await

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 mô hình mã thông báo, xoá mô-đun gapi.auth2 và gọi API bằng Thư viện ứng dụng API của Google cho JavaScript.

Các Lời hứa, không đồng bộ và chờ được dùng để thực thi thứ tự tải thư viện cũng như để phát hiện 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 cần nhấn nút "Show Calendar" (Hiện lịch) khi thiếu mã truy cập trong lần tải trang đầ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 mô hình mã thông báo, xoá mô-đun gapi.auth2 và gọi API bằng Thư viện ứng dụng API của Google cho JavaScript.

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

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 và nhấn lần nữa khi họ muốn làm mới thông tin trên Lịch.

<!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ụ Google Identity có thể sử dụng lệnh chuyển hướng URL để trực tiếp trả về mã uỷ quyền về điểm cuối của mã thông báo phụ trợ hoặc một trình xử lý gọi lại JavaScript chạy trong trình duyệt của người dùng giúp uỷ quyền phản hồi cho 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 để nhận đượ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ủ

Tính năng Đăng nhập bằng Google cho các ứ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 lệnh chuyển hướng đến Google để xin phép 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ợ. Sự đồng ý của người dùng được xử lý 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 của hệ thống thông tin địa lý (GIS)

Ví dụ này chỉ cho thấy thư viện JavaScript của Dịch vụ nhận dạng của Google bằng mô hình mã uỷ quyền, một hộp thoại bật lên để lấy sự đồng ý của người dùng và trình xử lý lệnh gọi lại để nhận mã uỷ quyền từ Google. Biểu mẫu này minh hoạ số bước tối thiểu cần thực hiện để định cấu hình một ứ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 của GIS

Mô hình mã uỷ quyền hỗ trợ chế độ trải nghiệm người dùng cửa sổ bật lên và chuyển hướ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ữ. Dưới đây là chế độ chuyển hướng cho trải nghiệm người dùng:

<!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, giúp hợp nhất và thay thế các tính năng và chức năng có trong nhiều thư viện và mô-đun:

Những việc cần thực hiện khi di chuyển sang Dịch vụ danh tính:

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à theo dõi 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 và thư viện Mới của Dịch vụ nhận dạng của Google cũng như Ghi chú cùng với thông tin bổ sung và hành động cần thực hiện trong quá trình di chuyển.

Mới Ghi chú
Đối tượng GoogleAuth và các phương thức liên quan:
GoogleAuth.attachClickHandler() Xóa
GoogleAuth.currentUser.get() Xóa
GoogleAuth.currentUser.listen() Xóa
GoogleAuth.disconnect() google.accounts.oauth2.revoke Thay cũ bằng mục mới. Bạn cũng có thể thu hồi 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 cũ bằng mục mới. Bạn cũng có thể thu hồi tại https://myaccount.google.com/permissions
GoogleUser.getAuthResponse() requestCode() or requestAccessToken() Thay cũ bằng giá mới
GoogleUser.getBasicProfile() Xóa. Thay vào đó, hãy sử dụng mã thông báo nhận dạng, hãy xem bài viết Di chuyển từ tính năng đăng nhập bằng Google.
GoogleUser.getGrantedScopes() hasGrantedAnyScope() Thay cũ bằng giá 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 cũ bằng giá mới
GoogleUser.isSignedIn() Xóa
GoogleUser.reloadAuthResponse() requestAccessToken() Xoá mã truy cập cũ, gọi mã 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:
đối tượng gapi.auth2.AuthorizeConfig TokenClientConfig hoặc CodeClientConfig Thay cũ bằng giá mới
Đối tượng gapi.auth2.AuthorizeResponse Xóa
Đối tượng gapi.auth2.AuthResponse Xóa
gapi.auth2.authorize() requestCode() or requestAccessToken() Thay cũ bằng giá mới
gapi.auth2.ClientConfig() TokenClientConfig hoặc CodeClientConfig Thay cũ bằng giá mới
gapi.auth2.getAuthInstance() Xóa
gapi.auth2.init() initTokenClient() or initCodeClient() Thay cũ bằng giá 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. Quá trình tải DOM HTML 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 hoạt động đăng nhập của người dùng vào Tài khoản Google.

Thông tin đăng nhập mẫu

Thông tin 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 của Google cho JavaScript hoặc các lệnh gọi trực tiếp đến điểm cuối của Google Auth 2.0 sẽ trả về cả mã truy cập OAuth 2.0 và Mã thông báo mã nhận dạng OpenID Connect trong một phản hồi.

Phản hồi mẫu 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 về 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ã thông báo nhận dạng khi được 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 của mã thông báo không hợp lệ

Ví dụ về phản hồi của Google khi bạn cố gắng tạo 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"
    }
  }