Sử dụng OAuth 2.0 cho ứng dụng từ máy chủ đến máy chủ

Hệ thống Google OAuth 2.0 hỗ trợ các tương tác giữa máy chủ với máy chủ, chẳng hạn như tương tác giữa một trang web ứng dụng và dịch vụ của Google. Trong trường hợp này, bạn cần có một tài khoản dịch vụ. là tài khoản thuộc về ứng dụng của bạn chứ không phải của một người dùng cuối cá nhân. Thông tin ứng dụng gọi Google API thay cho tài khoản dịch vụ, vì vậy, người dùng không trực tiếp liên quan. Trường hợp này đôi khi được gọi là "OAuth hai bên" hoặc "2LO". (Thuật ngữ có liên quan "OAuth ba bên" đề cập đến các tình huống trong đó ứng dụng của bạn gọi API của Google thay mặt người dùng cuối và đôi khi cần có sự đồng ý của người dùng).

Thông thường, ứng dụng dùng tài khoản dịch vụ khi ứng dụng đó dùng API của Google để hoạt động với dữ liệu của riêng mình thay vì dữ liệu của người dùng. Ví dụ: một ứng dụng sử dụng Google Cloud Kho dữ liệu dành cho tính năng lưu trữ cố định dữ liệu sẽ sử dụng tài khoản dịch vụ để xác thực lệnh gọi đến API Google Cloud Datastore.

Quản trị viên miền Google Workspace cũng có thể cấp quyền trên toàn miền cho tài khoản dịch vụ để truy cập người dùng thay mặt cho người dùng trong miền.

Tài liệu này mô tả cách một ứng dụng có thể hoàn tất quy trình OAuth 2.0 từ máy chủ đến máy chủ bằng cách bằng cách sử dụng thư viện ứng dụng API của Google (nên dùng) hoặc HTTP.

Tổng quan

Để hỗ trợ các hoạt động tương tác giữa các máy chủ, trước tiên, hãy tạo một tài khoản dịch vụ cho dự án của bạn trong API Console. Nếu bạn muốn truy cập vào dữ liệu người dùng của người dùng trong tài khoản Google Workspace của bạn, sau đó uỷ quyền truy cập trên toàn miền vào tài khoản dịch vụ.

Sau đó, ứng dụng của bạn chuẩn bị thực hiện lệnh gọi API được uỷ quyền bằng cách sử dụng để yêu cầu mã truy cập từ máy chủ xác thực OAuth 2.0.

Cuối cùng, ứng dụng của bạn có thể dùng mã truy cập để gọi API của Google.

Tạo một tài khoản dịch vụ

Thông tin đăng nhập của tài khoản dịch vụ bao gồm địa chỉ email được tạo riêng biệt và tối thiểu một cặp khoá công khai/riêng tư. Nếu bạn bật tính năng uỷ quyền trên toàn miền, thì mã ứng dụng khách cũng là một phần về thông tin đăng nhập của tài khoản dịch vụ.

Nếu ứng dụng của bạn chạy trên Google App Engine, thì tài khoản dịch vụ sẽ tự động được thiết lập khi bạn tạo dự án.

Nếu ứng dụng của bạn chạy trên Google Compute Engine, thì một tài khoản dịch vụ cũng được thiết lập tự động khi bạn tạo dự án, nhưng bạn phải chỉ định phạm vi mà ứng dụng cần quyền truy cập khi bạn tạo một phiên bản Google Compute Engine. Để biết thêm thông tin, xem Chuẩn bị một thực thể để sử dụng tài khoản dịch vụ.

Nếu ứng dụng của bạn không chạy trên Google App Engine hoặc Google Compute Engine, bạn phải lấy các thông tin đăng nhập này trong Google API Console. Cách tạo tài khoản dịch vụ hoặc để xem thông tin đăng nhập công khai mà bạn đã tạo, hãy làm như sau:

Đầu tiên, tạo một tài khoản dịch vụ:

  1. Mở Service accounts page.
  2. If prompted, select a project, or create a new one.
  3. Nhấp vào Tạo tài khoản dịch vụ .
  4. Trong Chi tiết tài khoản dịch vụ , nhập tên, ID và mô tả cho tài khoản dịch vụ, sau đó nhấp vào Tạo và tiếp tục .
  5. Tùy chọn: Trong phần Cấp quyền truy cập tài khoản dịch vụ này cho dự án , hãy chọn vai trò IAM để cấp cho tài khoản dịch vụ.
  6. Nhấp vào Tiếp tục .
  7. Tùy chọn: Trong Cấp cho người dùng quyền truy cập vào tài khoản dịch vụ này , thêm người dùng hoặc nhóm được phép sử dụng và quản lý tài khoản dịch vụ.
  8. Nhấp vào Xong .

Tiếp theo, tạo khóa tài khoản dịch vụ:

  1. Nhấp vào địa chỉ email cho tài khoản dịch vụ mà bạn đã tạo.
  2. Nhấp vào tab Phím .
  3. Trong danh sách thả xuống Thêm khóa , chọn Tạo khóa mới .
  4. Nhấp vào Tạo .

Cặp khóa công khai/riêng tư mới của bạn được tạo và tải xuống máy của bạn; nó đóng vai trò là bản sao duy nhất của khóa riêng. Bạn có trách nhiệm lưu trữ nó một cách an toàn. Nếu bạn làm mất cặp khóa này, bạn sẽ phải tạo một cặp khóa mới.

Bạn có thể quay lại API Console bất cứ lúc nào để xem địa chỉ email, công khai tệp tham chiếu khoá và các thông tin khác hoặc để tạo thêm cặp khoá công khai/riêng tư. Để thông tin chi tiết khác về thông tin đăng nhập tài khoản dịch vụ trong API Console, xem Tài khoản dịch vụ trong API Console tệp trợ giúp.

Ghi lại địa chỉ email của tài khoản dịch vụ và lưu trữ khoá riêng tư của tài khoản dịch vụ ở vị trí mà ứng dụng của bạn có thể truy cập. Ứng dụng của bạn cần các công cụ này thực hiện lệnh gọi API được uỷ quyền.

Uỷ quyền quyền trên toàn miền cho tài khoản dịch vụ

Khi sử dụng tài khoản Google Workspace, quản trị viên Workspace của tổ chức có thể cấp quyền để truy cập vào dữ liệu người dùng trên Workspace thay mặt cho người dùng trong miền Google Workspace. Ví dụ: ứng dụng sử dụng API Lịch Google để thêm sự kiện vào lịch của tất cả người dùng trong một miền Google Workspace sẽ sử dụng tài khoản dịch vụ để truy cập vào API Lịch Google thông qua thay mặt cho người dùng. Việc uỷ quyền cho một tài khoản dịch vụ thay mặt người dùng trong miền truy cập vào dữ liệu là đôi khi được gọi là "uỷ quyền cơ quan trên toàn miền" với một tài khoản dịch vụ.

Để uỷ quyền trên toàn miền cho một tài khoản dịch vụ, một quản trị viên cấp cao của Google Miền Workspace phải hoàn tất các bước sau:

  1. Từ miền của miền Google Workspace của bạn Bảng điều khiển dành cho quản trị viên, chuyển tới Trình đơn chính > Bảo mật > Quyền truy cập và kiểm soát dữ liệu > Các tuỳ chọn kiểm soát API.
  2. Trong ngăn Uỷ quyền trên toàn miền, hãy chọn Quản lý tính năng uỷ quyền trên toàn miền.
  3. Nhấp vào Thêm mới.
  4. Trong trường Mã khách hàng, hãy nhập Mã khách hàng của tài khoản dịch vụ. Bạn có thể tìm thấy mã ứng dụng khách của tài khoản dịch vụ của bạn trong Service accounts page.
  5. Trong trường Phạm vi OAuth (được phân tách bằng dấu phẩy), hãy nhập danh sách các phạm vi mà ứng dụng phải được cấp quyền truy cập. Ví dụ: nếu ứng dụng của bạn cần trên toàn miền toàn quyền truy cập vào API Google Drive và API Lịch Google, nhập: https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/calendar.
  6. Nhấp vào Uỷ quyền.

Ứng dụng của bạn hiện có quyền thực hiện lệnh gọi API với tư cách là người dùng trong miền Workspace của bạn (để "mạo danh" người dùng). Khi chuẩn bị thực hiện các lệnh gọi API được uỷ quyền này, bạn sẽ chỉ định rõ người dùng cần mạo danh.

Đang chuẩn bị thực hiện lệnh gọi API được uỷ quyền

Java

Sau khi bạn có được địa chỉ email khách hàng và khoá riêng tư từ API Console, hãy sử dụng Thư viện ứng dụng API của Google dành cho Java để tạo đối tượng GoogleCredential từ thông tin xác thực của tài khoản dịch vụ và các phạm vi mà ứng dụng của bạn cần quyền truy cập. Ví dụ:

import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.services.sqladmin.SQLAdminScopes;

// ...

GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"))
    .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN));

Nếu đang phát triển một ứng dụng trên Google Cloud Platform, bạn có thể sử dụng thông tin xác thực mặc định của ứng dụng để giúp đơn giản hoá quy trình.

Uỷ quyền quyền trên toàn miền

Nếu bạn đã uỷ quyền truy cập trên toàn miền vào tài khoản dịch vụ và bạn muốn mạo danh tài khoản người dùng, hãy chỉ định địa chỉ email của tài khoản người dùng có Phương thức createDelegated của đối tượng GoogleCredential. Ví dụ:

GoogleCredential credential = GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"))
    .createScoped(Collections.singleton(SQLAdminScopes.SQLSERVICE_ADMIN))
    .createDelegated("workspace-user@example.com");

Mã ở trên sử dụng đối tượng GoogleCredential để gọi createDelegated() . Đối số cho phương thức createDelegated() phải là một người dùng thuộc Workspace. Mã của bạn đưa ra yêu cầu sẽ sử dụng thông tin đăng nhập này để gọi Google API bằng tài khoản dịch vụ của bạn.

Python

Sau khi bạn có được địa chỉ email khách hàng và khoá riêng tư từ API Console, hãy sử dụng Thư viện ứng dụng API của Google dành cho Python để hoàn tất các bước sau:

  1. Tạo đối tượng Credentials từ thông tin xác thực của tài khoản dịch vụ và mà ứng dụng của bạn cần quyền truy cập. Ví dụ:
    from google.oauth2 import service_account
    
    SCOPES = ['https://www.googleapis.com/auth/sqlservice.admin']
    SERVICE_ACCOUNT_FILE = '/path/to/service.json'
    
    credentials = service_account.Credentials.from_service_account_file(
            SERVICE_ACCOUNT_FILE, scopes=SCOPES)

    Nếu đang phát triển một ứng dụng trên Google Cloud Platform, bạn có thể sử dụng thông tin xác thực mặc định của ứng dụng để giúp đơn giản hoá quy trình.

  2. Uỷ quyền quyền trên toàn miền

    Nếu bạn đã uỷ quyền truy cập trên toàn miền vào tài khoản dịch vụ và muốn mạo danh tài khoản người dùng, hãy sử dụng phương thức with_subject của Đối tượng ServiceAccountCredentials. Ví dụ:

    delegated_credentials = credentials.with_subject('user@example.org')

Sử dụng đối tượng Thông tin xác thực để gọi các API của Google trong ứng dụng của bạn.

HTTP/REST

Sau khi bạn có được ID ứng dụng khách và khoá riêng tư từ API Consolethân mến, đơn đăng ký của bạn cần hoàn tất các bước sau:

  1. Tạo Mã thông báo web JSON (JWT, phát âm là "jot") bao gồm tiêu đề, tập hợp thông báo xác nhận quyền sở hữu và một chữ ký.
  2. Yêu cầu mã truy cập từ Máy chủ uỷ quyền Google OAuth 2.0.
  3. Xử lý phản hồi JSON mà Máy chủ uỷ quyền trả về.

Các phần sau đây sẽ mô tả cách hoàn thành các bước này.

Nếu phản hồi có chứa mã truy cập, bạn có thể sử dụng mã truy cập để gọi một API của Google. (Nếu câu trả lời không bao gồm quyền truy cập mã thông báo, yêu cầu JWT và mã thông báo của bạn có thể không được định dạng đúng cách hoặc tài khoản dịch vụ có thể không có quyền truy cập vào phạm vi được yêu cầu.)

Khi mã truy cập hết hạn, ứng dụng của bạn sẽ tạo một mã truy cập khác JWT, ký tên rồi yêu cầu một mã truy cập khác.

Ứng dụng máy chủ của bạn sử dụng JWT để yêu cầu mã thông báo từ Google
                  Ủy quyền, sau đó sử dụng mã thông báo này để gọi một điểm cuối API của Google. Không
                  có liên quan đến người dùng cuối.

Phần còn lại của phần này mô tả các chi tiết cụ thể của việc tạo JWT, ký JWT, tạo yêu cầu mã truy cập và xử lý phản hồi.

Tạo JWT

JWT bao gồm ba phần: tiêu đề, nhóm thông báo xác nhận quyền sở hữu và của bạn. Tiêu đề và nhóm thông báo xác nhận quyền sở hữu là các đối tượng JSON. Các đối tượng JSON này được chuyển đổi tuần tự thành UTF-8 byte, sau đó được mã hoá bằng bộ mã hoá Base64url. Phương thức mã hoá này đảm bảo khả năng phục hồi đối với những thay đổi về mã hoá do các thao tác mã hoá lặp lại. Tiêu đề, nhóm xác nhận quyền sở hữu và chữ ký được nối với nhau bằng ký tự dấu chấm (.).

JWT có cấu trúc như sau:

{Base64url encoded header}.{Base64url encoded claim set}.{Base64url encoded signature}

Chuỗi cơ sở cho chữ ký như sau:

{Base64url encoded header}.{Base64url encoded claim set}
Tạo tiêu đề JWT

Tiêu đề bao gồm ba trường cho biết thuật toán ký, định dạng câu nhận định và [mã khoá của tài khoản dịch vụ key](https://cloud.google.com/iam/docs/reference/rest/v1/projects.serviceAccounts.keys) được dùng để ký JWT. Thuật toán và định dạng là bắt buộc và mỗi trường chỉ một giá trị. Khi các thuật toán và định dạng bổ sung được đưa vào, tiêu đề này sẽ thay đổi cho phù hợp. Mã khoá là không bắt buộc và nếu bạn chỉ định mã khoá không chính xác, GCP sẽ thử tất cả khoá được liên kết với tài khoản dịch vụ để xác minh mã thông báo và từ chối mã thông báo nếu không tìm thấy khoá hợp lệ nào. Google giữ quyền từ chối những mã thông báo có mã khoá không chính xác trong tương lai.

Các tài khoản dịch vụ sử dụng thuật toán SHA-256 RSA và định dạng mã thông báo JWT. Do đó, JSON đại diện cho tiêu đề như sau:

{"alg":"RS256","typ":"JWT", "kid":"370ab79b4513eb9bad7c9bd16a95cb76b5b2a56a"}

Dưới đây là cách biểu thị Base64url:

          eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsICJraWQiOiIzNzBhYjc5YjQ1MTNlYjliYWQ3YzliZDE2YTk1Y2I3NmI1YjJhNTZhIn0=
Tạo nhóm thông báo xác nhận quyền sở hữu JWT

Nhóm thông báo xác nhận quyền sở hữu JWT chứa thông tin về JWT, bao gồm cả các quyền đang được (phạm vi), mục tiêu của mã thông báo, nhà phát hành, thời điểm phát hành mã thông báo, và vòng đời của mã thông báo. Hầu hết các trường đều là bắt buộc. Giống như tiêu đề JWT, Nhóm thông báo xác nhận quyền sở hữu JWT là một đối tượng JSON và được dùng để tính toán chữ ký.

Thông báo xác nhận quyền sở hữu bắt buộc

Các thông báo xác nhận quyền sở hữu bắt buộc trong nhóm thông báo xác nhận quyền sở hữu JWT sẽ xuất hiện bên dưới. Chúng có thể xuất hiện theo thứ tự bất kỳ trong xác nhận quyền sở hữu được đặt.

Tên Mô tả
iss Địa chỉ email của tài khoản dịch vụ.
scope Danh sách các quyền mà ứng dụng yêu cầu, được phân tách bằng dấu cách.
aud Phần mô tả mục tiêu dự kiến của câu nhận định. Khi tạo mã truy cập giá trị này luôn là https://oauth2.googleapis.com/token.
exp Thời gian hết hạn xác nhận, được chỉ định bằng giây kể từ 00:00:00 giờ UTC, Ngày 1 tháng 1 năm 1970. Giá trị này tối đa là 1 giờ sau thời gian phát hành.
iat Thời gian đưa ra khẳng định, được chỉ định là giây kể từ 00:00:00 giờ UTC, Ngày 1 tháng 1 năm 1970.

Dưới đây là nội dung trình bày JSON của các trường bắt buộc trong nhóm thông báo xác nhận quyền sở hữu JWT:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "scope": "https://www.googleapis.com/auth/devstorage.read_only",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
Thông báo xác nhận quyền sở hữu khác

Trong một số trường hợp doanh nghiệp, một ứng dụng có thể sử dụng tính năng uỷ quyền trên toàn miền để hành động thay mặt của một người dùng cụ thể trong tổ chức. Quyền thực hiện kiểu mạo danh này phải được cấp trước khi ứng dụng có thể mạo danh người dùng và thường được xử lý bằng quản trị viên cấp cao. Để biết thêm thông tin, hãy xem Kiểm soát quyền truy cập API bằng tính năng uỷ quyền trên toàn miền.

Để lấy mã truy cập cấp cho một ứng dụng được uỷ quyền truy cập vào một tài nguyên, Bạn có thể đặt địa chỉ email của người dùng trong yêu cầu xác nhận quyền sở hữu JWT làm giá trị của Trường sub.

Tên Mô tả
sub Địa chỉ email của người dùng mà ứng dụng đang yêu cầu uỷ quyền truy cập.

Nếu ứng dụng không có quyền mạo danh người dùng, phản hồi với yêu cầu mã truy cập bao gồm trường sub sẽ là một lỗi.

Ví dụ về tập hợp thông báo xác nhận quyền sở hữu JWT có trường sub bên dưới:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "sub": "some.user@example.com",
  "scope": "https://www.googleapis.com/auth/prediction",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
Mã hoá nhóm thông báo xác nhận quyền sở hữu JWT

Giống như tiêu đề JWT, tập hợp xác nhận quyền sở hữu JWT phải được chuyển đổi tuần tự thành UTF-8 và Base64url an toàn được mã hoá. Dưới đây là ví dụ về cách trình bày JSON của một tập hợp Thông báo xác nhận quyền sở hữu JWT:

{
  "iss": "761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
  "scope": "https://www.googleapis.com/auth/prediction",
  "aud": "https://oauth2.googleapis.com/token",
  "exp": 1328554385,
  "iat": 1328550785
}
Tính toán chữ ký

Chữ ký web JSON (JWS) là quy cách hướng dẫn cơ chế tạo chữ ký cho JWT. Dữ liệu đầu vào cho chữ ký là mảng byte của nội dung sau:

{Base64url encoded header}.{Base64url encoded claim set}

Bạn phải sử dụng thuật toán ký trong tiêu đề JWT khi tính toán chữ ký. Chiến lược phát hành đĩa đơn thuật toán ký duy nhất được Máy chủ ủy quyền Google OAuth 2.0 hỗ trợ là RSA sử dụng Thuật toán băm SHA-256. Điều này được biểu thị dưới dạng RS256 trong alg trong tiêu đề JWT.

Ký biểu diễn UTF-8 của đầu vào bằng SHA256withRSA (còn được gọi là RSASSA-PKCS1-V1_5-SIGN với hàm băm SHA-256) với khóa riêng lấy từ Google API Console. Kết quả đầu ra sẽ là một mảng byte.

Sau đó, chữ ký phải được mã hoá Base64url. Tiêu đề, tập hợp xác nhận quyền sở hữu và chữ ký được nối với nhau bằng một ký tự dấu chấm (.). Kết quả là JWT. Nó nên như sau (thêm ngắt dòng để cho rõ ràng):

{Base64url encoded header}.
{Base64url encoded claim set}.
{Base64url encoded signature}

Dưới đây là ví dụ về JWT trước khi mã hoá Base64url:

{"alg":"RS256","typ":"JWT"}.
{
"iss":"761326798069-r5mljlln1rd4lrbhg75efgigp36m78j5@developer.gserviceaccount.com",
"scope":"https://www.googleapis.com/auth/prediction",
"aud":"https://oauth2.googleapis.com/token",
"exp":1328554385,
"iat":1328550785
}.
[signature bytes]

Dưới đây là ví dụ về một JWT đã được ký và sẵn sàng truyền:

eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL29hdXRoMi92NC90b2tlbiIsImV4cCI6MTMyODU1NDM4NSwiaWF0IjoxMzI4NTUwNzg1fQ.UFUt59SUM2_AW4cRU8Y0BYVQsNTo4n7AFsNrqOpYiICDu37vVt-tw38UKzjmUKtcRsLLjrR3gFW3dNDMx_pL9DVjgVHDdYirtrCekUHOYoa1CMR66nxep5q5cBQ4y4u2kIgSvChCTc9pmLLNoIem-ruCecAJYgI9Ks7pTnW1gkOKs0x3YpiLpzplVHAkkHztaXiJdtpBcY1OXyo6jTQCa3Lk2Q3va1dPkh_d--GU2M5flgd8xNBPYw4vxyt0mP59XZlHMpztZt0soSgObf7G3GXArreF_6tpbFsS3z2t5zkEiHuWJXpzcYr5zWTRPDEHsejeBSG8EgpLDce2380ROQ

Tạo yêu cầu mã truy cập

Sau khi tạo JWT đã ký, ứng dụng có thể sử dụng JWT đó để yêu cầu mã truy cập. Yêu cầu mã truy cập này là một yêu cầu HTTPS POST và nội dung là URL được mã hoá. URL được hiển thị dưới đây:

https://oauth2.googleapis.com/token

Các tham số sau đây là bắt buộc trong yêu cầu POST HTTPS:

Tên Mô tả
grant_type Sử dụng chuỗi sau, được mã hoá URL khi cần thiết: urn:ietf:params:oauth:grant-type:jwt-bearer
assertion JWT, bao gồm cả chữ ký.

Dưới đây là tệp kết xuất thô của yêu cầu HTTPS POST được dùng trong mã truy cập yêu cầu:

POST /token HTTP/1.1
Host: oauth2.googleapis.com
Content-Type: application/x-www-form-urlencoded

grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.ixOUGehweEVX_UKXv5BbbwVEdcz6AYS-6uQV6fGorGKrHf3LIJnyREw9evE-gs2bmMaQI5_UbabvI4k-mQE4kBqtmSpTzxYBL1TCd7Kv5nTZoUC1CmwmWCFqT9RE6D7XSgPUh_jF1qskLa2w0rxMSjwruNKbysgRNctZPln7cqQ

Dưới đây là yêu cầu tương tự, sử dụng curl:

curl -d 'grant_type=urn%3Aietf%3Aparams%3Aoauth%3Agrant-type%3Ajwt-bearer&assertion=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiI3NjEzMjY3OTgwNjktcjVtbGpsbG4xcmQ0bHJiaGc3NWVmZ2lncDM2bTc4ajVAZGV2ZWxvcGVyLmdzZXJ2aWNlYWNjb3VudC5jb20iLCJzY29wZSI6Imh0dHBzOi8vd3d3Lmdvb2dsZWFwaXMuY29tL2F1dGgvcHJlZGljdGlvbiIsImF1ZCI6Imh0dHBzOi8vYWNjb3VudHMuZ29vZ2xlLmNvbS9vL29hdXRoMi90b2tlbiIsImV4cCI6MTMyODU3MzM4MSwiaWF0IjoxMzI4NTY5NzgxfQ.RZVpzWygMLuL-n3GwjW1_yhQhrqDacyvaXkuf8HcJl8EtXYjGjMaW5oiM5cgAaIorrqgYlp4DPF_GuncFqg9uDZrx7pMmCZ_yHfxhSCXru3gbXrZvAIicNQZMFxrEEn4REVuq7DjkTMyCMGCY1dpMa8aWfTQFt3Eh7smLchaZsU
' https://oauth2.googleapis.com/token

Xử lý phản hồi

Nếu yêu cầu JWT và mã truy cập được định dạng đúng cách và tài khoản dịch vụ đã quyền thực hiện thao tác, sau đó phản hồi JSON từ Máy chủ ủy quyền có bao gồm một mã truy cập. Sau đây là một phản hồi mẫu:

{
  "access_token": "1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M",
  "scope": "https://www.googleapis.com/auth/prediction"
  "token_type": "Bearer",
  "expires_in": 3600
}

Mã truy cập có thể được sử dụng lại trong khoảng thời gian do Giá trị expires_in.

Gọi API của Google

Java

Sử dụng đối tượng GoogleCredential để gọi các API của Google bằng cách hoàn tất các bước sau:

  1. Tạo đối tượng dịch vụ cho API mà bạn muốn gọi bằng cách sử dụng Đối tượng GoogleCredential. Ví dụ:
    SQLAdmin sqladmin =
        new SQLAdmin.Builder(httpTransport, JSON_FACTORY, credential).build();
  2. Gửi yêu cầu đến dịch vụ API bằng giao diện do đối tượng dịch vụ cung cấp. Ví dụ: để liệt kê các thực thể của cơ sở dữ liệu Cloud SQL trong ví dụ thú vị -example-123 dự án:
    SQLAdmin.Instances.List instances =
        sqladmin.instances().list("exciting-example-123").execute();

Python

Sử dụng đối tượng Credentials được uỷ quyền để gọi các API của Google bằng cách hoàn tất các bước sau:

  1. Tạo đối tượng dịch vụ cho API mà bạn muốn gọi. Bạn tạo một đối tượng dịch vụ bằng cách gọi hàm build với tên, phiên bản của API và đối tượng Credentials được uỷ quyền. Ví dụ: để gọi phiên bản 1beta3 của API Quản trị Cloud SQL:
    import googleapiclient.discovery
    
    sqladmin = googleapiclient.discovery.build('sqladmin', 'v1beta3', credentials=credentials)
  2. Gửi yêu cầu đến dịch vụ API bằng giao diện do đối tượng dịch vụ cung cấp. Ví dụ: để liệt kê các thực thể của cơ sở dữ liệu Cloud SQL trong ví dụ thú vị -example-123 dự án:
    response = sqladmin.instances().list(project='exciting-example-123').execute()

HTTP/REST

Sau khi ứng dụng của bạn nhận được mã truy cập, bạn có thể sử dụng mã này để thực hiện lệnh gọi đến Google API thay mặt cho một tài khoản dịch vụ cụ thể hoặc tài khoản người dùng nếu(các) phạm vi quyền truy cập mà API yêu cầu đã được cấp. Để thực hiện việc này, hãy thêm mã truy cập trong yêu cầu gửi đến API bằng cách bao gồm truy vấn access_token hoặc một giá trị Bearer của tiêu đề HTTP Authorization. Nếu có thể, nên ưu tiên sử dụng tiêu đề HTTP vì chuỗi truy vấn thường hiển thị trong nhật ký máy chủ. Trong hầu hết bạn có thể sử dụng thư viện ứng dụng để thiết lập lệnh gọi đến các API của Google (ví dụ: khi gọi API Tệp Drive).

Bạn có thể dùng thử tất cả API của Google và xem phạm vi của chúng ở Chơi ứng dụng OAuth 2.0.

Ví dụ về HTTP GET

Lệnh gọi đến drive.files điểm cuối (API Tệp Drive) bằng HTTP Authorization: Bearer có thể có dạng như sau. Xin lưu ý rằng bạn cần chỉ định mã truy cập của riêng mình:

GET /drive/v2/files HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

Dưới đây là lệnh gọi đến cùng một API cho người dùng đã được xác thực bằng access_token tham số chuỗi truy vấn:

GET https://www.googleapis.com/drive/v2/files?access_token=access_token

Ví dụ về curl

Bạn có thể kiểm thử các lệnh này bằng ứng dụng dòng lệnh curl. Sau đây là một ví dụ sử dụng tuỳ chọn tiêu đề HTTP (ưu tiên):

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/drive/v2/files

Hoặc, một cách khác là tuỳ chọn tham số chuỗi truy vấn:

curl https://www.googleapis.com/drive/v2/files?access_token=access_token

Khi mã truy cập hết hạn

Mã thông báo truy cập do Máy chủ uỷ quyền Google OAuth 2.0 cấp sẽ hết hạn sau khoảng thời gian đó do giá trị expires_in cung cấp. Khi mã truy cập hết hạn, thì ứng dụng sẽ tạo một JWT khác, ký tên đó và yêu cầu một mã truy cập khác.

Mã lỗi JWT

error trường error_description trường Ý nghĩa Cách giải quyết
unauthorized_client Unauthorized client or scope in request. Nếu bạn đang cố gắng sử dụng tính năng uỷ quyền trên toàn miền thì tài khoản dịch vụ này chưa được cấp quyền trong Bảng điều khiển dành cho quản trị viên của miền của người dùng.

Hãy đảm bảo rằng tài khoản dịch vụ được uỷ quyền trong Trang uỷ quyền trên toàn miền của Bảng điều khiển dành cho quản trị viên cho người dùng trong Thông báo xác nhận quyền sở hữu sub (trường).

Mặc dù quá trình này thường mất vài phút nhưng có thể mất đến 24 giờ để quá trình uỷ quyền áp dụng cho tất cả người dùng trong Tài khoản Google của bạn.

unauthorized_client Client is unauthorized to retrieve access tokens using this method, or client not authorized for any of the scopes requested. Một tài khoản dịch vụ đã được uỷ quyền bằng địa chỉ email ứng dụng khách thay vì mã ứng dụng khách (số) trong Bảng điều khiển dành cho quản trị viên. Trong Trang Uỷ quyền trên toàn miền trong Bảng điều khiển dành cho quản trị viên, hãy xoá rồi thêm lại ứng dụng với mã nhận dạng dạng số.
access_denied (giá trị bất kỳ) Nếu bạn đang sử dụng tính năng uỷ quyền trên toàn miền, thì một hoặc nhiều phạm vi đã yêu cầu không được phép trong Bảng điều khiển dành cho quản trị viên.

Hãy đảm bảo rằng tài khoản dịch vụ được uỷ quyền trong trang uỷ quyền trên toàn miền của Bảng điều khiển dành cho quản trị viên cho người dùng trong sub xác nhận quyền sở hữu (trường) và bao gồm tất cả các phạm vi mà bạn yêu cầu trong thông báo xác nhận quyền sở hữu scope của JWT.

Mặc dù quá trình này thường mất vài phút nhưng quá trình uỷ quyền có thể mất đến 24 giờ áp dụng cho tất cả người dùng trong Tài khoản Google của bạn.

admin_policy_enforced (giá trị bất kỳ) Tài khoản Google không thể cấp quyền cho một hoặc nhiều phạm vi đã yêu cầu do chính sách của quản trị viên Google Workspace của họ.

Xem bài viết trợ giúp dành cho Quản trị viên Google Workspace Kiểm soát bên thứ ba và các ứng dụng nội bộ truy cập vào dữ liệu trong Google Workspace để biết thêm thông tin về cách quản trị viên có thể hạn chế quyền truy cập ở tất cả các phạm vi hoặc các phạm vi nhạy cảm và bị hạn chế cho đến khi quyền truy cập được cấp rõ ràng cho ID ứng dụng khách OAuth của bạn.

invalid_client (giá trị bất kỳ)

Ứng dụng OAuth hoặc mã thông báo JWT không hợp lệ hoặc được định cấu hình không chính xác.

Hãy tham khảo phần mô tả lỗi để biết thông tin chi tiết.

Đảm bảo mã thông báo JWT hợp lệ và chứa các thông báo xác nhận quyền sở hữu chính xác.

Kiểm tra để đảm bảo rằng tài khoản dịch vụ và ứng dụng OAuth được định cấu hình đúng cách và bạn đang sử dụng đúng địa chỉ email.

Hãy kiểm tra để đảm bảo mã thông báo JWT là chính xác và đã được cấp cho mã ứng dụng khách trong của bạn.

invalid_grant Not a valid email. Người dùng không tồn tại. Hãy kiểm tra để đảm bảo rằng địa chỉ email trong trường (trường) xác nhận quyền sở hữu sub là chính xác.
invalid_grant

Invalid JWT: Token must be a short-lived token (60 minutes) and in a reasonable timeframe. Check your 'iat' and 'exp' values and use a clock with skew to account for clock differences between systems.

Thông thường, điều đó có nghĩa là giờ hệ thống địa phương không chính xác. Điều này cũng có thể xảy ra nếu Giá trị exp sẽ lớn hơn 65 phút trong tương lai từ giá trị iat, hoặc giá trị exp thấp hơn giá trị iat.

Hãy đảm bảo rằng đồng hồ trên hệ thống nơi JWT được tạo là chính xác. Nếu nếu cần, hãy đồng bộ hoá thời gian của bạn với NTP của Google.

invalid_grant Invalid JWT Signature.

Xác nhận JWT được ký bằng một khoá riêng tư không liên kết với tài khoản dịch vụ được xác định bằng email của ứng dụng hoặc khoá được sử dụng đã bị xoá, vô hiệu hoá hoặc đã hết hạn.

Ngoài ra, xác nhận JWT có thể được mã hoá không chính xác – nó phải Được mã hoá Base64, không có các dòng mới hoặc khoảng đệm bằng dấu bằng.

Giải mã tập hợp thông báo xác nhận quyền sở hữu JWT và xác minh khoá đã liên kết với câu nhận định thông qua tài khoản dịch vụ.

Thử dùng một thư viện OAuth do Google cung cấp để đảm bảo tạo JWT đúng cách.

invalid_scope Invalid OAuth scope or ID token audience provided. Không có phạm vi nào được yêu cầu (danh sách phạm vi trống) hoặc một trong các phạm vi được yêu cầu không tồn tại (tức là không hợp lệ).

Đảm bảo rằng thông báo xác nhận quyền sở hữu scope (trường) của JWT được điền sẵn rồi so sánh phạm vi mà tệp đó chứa với các phạm vi được nêu trong tài liệu cho những API bạn muốn sử dụng, để đảm bảo không có lỗi hoặc lỗi đánh máy.

Lưu ý rằng danh sách phạm vi trong thông báo xác nhận quyền sở hữu scope cần được phân tách bằng dấu cách, chứ không phải dấu phẩy.

disabled_client The OAuth client was disabled. Khoá dùng để ký xác nhận JWT bị tắt.

Truy cập vào Google API Consolevà trong IAM & Bảng điều khiển dành cho quản trị viên > Tài khoản dịch vụ, bật tài khoản dịch vụ chứa "Mã khoá" đã dùng để ký nhận định.

org_internal This client is restricted to users within its organization. Mã ứng dụng OAuth trong yêu cầu thuộc một dự án giới hạn quyền truy cập vào Google Tài khoản trong một Tổ chức Google Cloud.

Hãy sử dụng tài khoản dịch vụ của tổ chức để xác thực. Xác nhận kiểu người dùng cấu hình cho ứng dụng OAuth.

Phụ lục: Uỷ quyền tài khoản dịch vụ không có OAuth

Với một số API của Google, bạn có thể thực hiện các lệnh gọi API được uỷ quyền bằng cách trực tiếp sử dụng JWT đã ký dưới dạng mã thông báo truy cập thay vì mã truy cập OAuth 2.0. Khi có thể, bạn có thể tránh để gửi yêu cầu mạng tới máy chủ uỷ quyền của Google trước khi thực hiện lệnh gọi API.

Nếu API bạn muốn gọi có định nghĩa về dịch vụ được xuất bản trong Kho lưu trữ GitHub của Google API, bạn có thể thực hiện lệnh gọi API được uỷ quyền bằng cách sử dụng JWT thay vì mã truy cập. Cách làm như sau:

  1. Tạo tài khoản dịch vụ như mô tả ở trên. Hãy nhớ giữ lại tệp JSON mà bạn nhận được khi tạo tài khoản.
  2. Sử dụng thư viện JWT chuẩn bất kỳ, chẳng hạn như thư viện có tại jwt.io, tạo JWT có tiêu đề và tải trọng như trong ví dụ sau:
    {
      "alg": "RS256",
      "typ": "JWT",
      "kid": "abcdef1234567890"
    }
    .
    {
      "iss": "123456-compute@developer.gserviceaccount.com",
      "sub": "123456-compute@developer.gserviceaccount.com",
      "aud": "https://firestore.googleapis.com/",
      "iat": 1511900000,
      "exp": 1511903600
    }
    • Đối với trường kid trong tiêu đề, hãy chỉ định khoá riêng tư của tài khoản dịch vụ của bạn Mã nhận dạng. Bạn có thể tìm thấy giá trị này trong trường private_key_id của tài khoản dịch vụ Tệp JSON.
    • Đối với các trường isssub, hãy chỉ định email cho tài khoản dịch vụ của bạn của bạn. Bạn có thể tìm thấy giá trị này trong trường client_email của dịch vụ tệp JSON của tài khoản.
    • Đối với trường aud, hãy chỉ định điểm cuối của API. Ví dụ: https://SERVICE.googleapis.com/.
    • Đối với trường iat, hãy chỉ định thời gian Unix hiện tại và cho giá trị Trường exp, chỉ định thời gian chính xác là 3.600 giây sau đó, khi JWT sẽ hết hạn.

Ký JWT bằng RSA-256 bằng khoá riêng tư có trong tệp JSON của tài khoản dịch vụ.

Ví dụ:

Java

Sử dụng google-api-java-clientjava-jwt:

GoogleCredential credential =
        GoogleCredential.fromStream(new FileInputStream("MyProject-1234.json"));
PrivateKey privateKey = credential.getServiceAccountPrivateKey();
String privateKeyId = credential.getServiceAccountPrivateKeyId();

long now = System.currentTimeMillis();

try {
    Algorithm algorithm = Algorithm.RSA256(null, privateKey);
    String signedJwt = JWT.create()
        .withKeyId(privateKeyId)
        .withIssuer("123456-compute@developer.gserviceaccount.com")
        .withSubject("123456-compute@developer.gserviceaccount.com")
        .withAudience("https://firestore.googleapis.com/")
        .withIssuedAt(new Date(now))
        .withExpiresAt(new Date(now + 3600 * 1000L))
        .sign(algorithm);
} catch ...

Python

Sử dụng PyJWT:

iat = time.time()
exp = iat + 3600
payload = {'iss': '123456-compute@developer.gserviceaccount.com',
           'sub': '123456-compute@developer.gserviceaccount.com',
           'aud': 'https://firestore.googleapis.com/',
           'iat': iat,
           'exp': exp}
additional_headers = {'kid': PRIVATE_KEY_ID_FROM_JSON}
signed_jwt = jwt.encode(payload, PRIVATE_KEY_FROM_JSON, headers=additional_headers,
                       algorithm='RS256')
  1. Gọi API, sử dụng JWT đã ký làm mã thông báo mang:
    GET /v1/projects/abc/databases/123/indexes HTTP/1.1
    Authorization: Bearer SIGNED_JWT
    Host: firestore.googleapis.com

Triển khai tính năng Bảo vệ nhiều tài khoản

Bạn nên thực hiện thêm một bước để bảo vệ đang triển khai tính năng Nhiều tài khoản Bảo vệ bằng cách sử dụng Dịch vụ bảo vệ nhiều tài khoản của Google. Dịch vụ này cho phép bạn đăng ký nhận thông báo sự kiện bảo mật nhằm cung cấp thông tin cho ứng dụng của bạn về những thay đổi lớn đối với tài khoản người dùng. Sau đó, bạn có thể sử dụng thông tin này để thực hiện hành động tuỳ thuộc vào cách bạn quyết định phản hồi sự kiện.

Dưới đây là một số ví dụ về các loại sự kiện mà Dịch vụ bảo vệ nhiều tài khoản của Google gửi tới ứng dụng của bạn:

  • https://schemas.openid.net/secevent/risc/event-type/sessions-revoked
  • https://schemas.openid.net/secevent/oauth/event-type/token-revoked
  • https://schemas.openid.net/secevent/risc/event-type/account-disabled

Xem Bảo vệ tài khoản người dùng bằng trang Bảo vệ nhiều tài khoản để biết thêm thông tin về cách triển khai tính năng Bảo vệ nhiều tài khoản và để biết danh sách đầy đủ các sự kiện hiện có.