Hệ thống Google OAuth 2.0 hỗ trợ tương tác từ máy chủ đến máy chủ, chẳng hạn như tương tác giữa ứng dụng web 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ụ. Tài khoản này là tài khoản của ứng dụng thay vì một người dùng cuối riêng lẻ. Ứng dụng của bạn sẽ gọi API Google thay mặt cho tài khoản dịch vụ để người dùng không phải trực tiếp tham gia. Trường hợp này đôi khi được gọi là "OAuth 2 bên" hoặc "2LO". (Thuật ngữ có liên quan "Ba bên trực tuyến" dùng để chỉ 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à trong đó có sự đồng ý của người dùng.)
Thông thường, ứng dụng sẽ sử dụng tài khoản dịch vụ khi ứng dụng đó sử dụng API của Google để làm việc 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 Datastore để lưu trữ dữ liệu sẽ sử dụng tài khoản dịch vụ để xác thực cá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 cho tài khoản dịch vụ quyền trên toàn miền quyền truy cập vào dữ liệu của 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 luồng OAuth 2.0 từ máy chủ đến máy chủ bằng cách sử dụng thư viện ứng dụng API Google (nên dùng) hoặc HTTP.
Tổng quan
Để hỗ trợ tương tác từ máy chủ đến 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, hãy uỷ quyền 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 ủy quyền bằng cách sử dụng thông tin đăng nhập của tài khoản dịch vụ để 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ể sử dụng mã truy cập để gọi API 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 một địa chỉ email đã tạo duy nhất và ít nhất một cặp khóa công khai/riêng tư. Nếu bạn đã bật tính năng ủy quyền trên toàn miền, thì mã ứng dụng khách cũng là một phần trong 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ì một tài khoản dịch vụ sẽ được thiết lập tự động 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 các phạm vi mà ứng dụng cần truy cập khi tạo một phiên bản Google Compute Engine. Để biết thêm thông tin, hãy xem phần Chuẩn bị một phiên bản để 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, thì bạn phải lấy những thông tin đăng nhập này trong Google API Console. Để tạo thông tin đăng nhập 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ụ:
- Mở Service accounts page.
- If prompted, select a project, or create a new one.
- Nhấp vào Tạo tài khoản dịch vụ .
- 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 .
- 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ụ.
- Nhấp vào Tiếp tục .
- 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ụ.
- Nhấp vào Xong .
Tiếp theo, tạo khóa tài khoản dịch vụ:
- Nhấp vào địa chỉ email cho tài khoản dịch vụ mà bạn đã tạo.
- Nhấp vào tab Phím .
- Trong danh sách thả xuống Thêm khóa , chọn Tạo khóa mới .
- 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, vân tay số của khóa công khai và thông tin khác, hoặc để tạo thêm các cặp khóa công khai/riêng tư. Để biết thêm thông tin chi tiết về thông tin đăng nhập của tài khoản dịch vụ trong API Console, hãy xem phần Tài khoản dịch vụ trong tệp trợ giúp API Console.
Hãy ghi lại địa chỉ email của tài khoản dịch vụ và lưu trữ tệp khóa cá nhân của tài khoản dịch vụ ở vị trí mà ứng dụng của bạn có thể truy cập được. Ứng dụng của bạn cần có các lệnh này để thực hiện lệnh gọi API được uỷ quyền.
Ủy 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ể thay mặt người dùng trong miền Google Workspace ủy quyền cho một ứng dụng truy cập vào dữ liệu người dùng Workspace. Ví dụ: một ứng dụng dùng API Lịch Google để thêm các sự kiện vào lịch của tất cả người dùng trong miền Google Workspace sẽ thay mặt người dùng truy cập vào API Lịch Google. Việc ủy quyền cho một tài khoản dịch vụ truy cập dữ liệu thay mặt cho người dùng trong một miền đôi khi được gọi là "ủy quyền trên toàn miền" cho một tài khoản dịch vụ.
Để ủy quyền toàn bộ miền cho một tài khoản dịch vụ, quản trị viên cấp cao của miền Google Workspace phải hoàn thành các bước sau:
- Từ Bảng điều khiển dành cho quản trị viên của miền Google Workspace, hãy chuyển đến Trình đơn chính > Bảo mật > Quyền truy cập và kiểm soát dữ liệu > Quyền kiểm soát API.
- Trong ngăn Ủy quyền trên toàn miền, hãy chọn Quản lý ủy quyền trên toàn miền.
- Nhấp vào Thêm mới.
- Trong trường Mã ứng dụng, hãy nhập Mã ứng dụ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ụ trong Service accounts page.
- Trong trường các phạm vi OAuth (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 của bạn sẽ được cấp quyền truy cập. Ví dụ: nếu ứng dụng của bạn cần quyền truy cập đầy đủ vào API Google Drive và API Lịch Google, hãy nhập: https://www.googleapis.com/auth/drive, https://www.googleapis.com/auth/calendar.
- 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 ủy quyền này, bạn sẽ chỉ định rõ ràng người dùng sẽ mạo danh.
Chuẩn bị thực hiện lệnh gọi API được ủy quyền
Java
Sau khi bạn lấy đị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 đăng nhập của tài khoản dịch vụ và 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ể dùng thông tin đăng nhập mặc định của ứng dụng để đơn giản hoá quy trình.
Ủy quyền trên toàn miền
Nếu bạn được ủy 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 đó bằng 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 phương thức createDelegated()
. Đối số cho phương thức createDelegated()
phải là người dùng thuộc
tài khoản Workspace của bạn. Mã của bạn yêu cầu sẽ sử dụng thông tin đăng nhập này để gọi các API
Google bằng tài khoản dịch vụ của bạn.
Python
Sau khi bạn lấy đị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:
- Tạo một đối tượng
Credentials
từ thông tin đăng nhập của tài khoản dịch vụ và phạm vi mà ứng dụng cầ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ể dùng thông tin đăng nhập mặc định của ứng dụng để đơn giản hoá quy trình.
- Ủy quyền trên toàn miền
Nếu bạn được ủy 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 một tài khoản người dùng, hãy sử dụng phương thức
with_subject
của đối tượngServiceAccountCredentials
hiện có. 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 API Google trong ứng dụng của bạn.
HTTP/REST
Sau khi bạn nhận được mã ứng dụng khách và khoá riêng tư từ API Console, ứng dụng của bạn cần hoàn tất các bước sau:
- Tạo một Mã thông báo Web JSON (JWT, phát âm là "jot") trong đó có tiêu đề, một thông báo xác nhận quyền sở hữu và một chữ ký.
- Yêu cầu mã thông báo truy cập từ Máy chủ uỷ quyền Google OAuth 2.0.
- Xử lý phản hồi JSON mà Máy chủ ủy quyền trả về.
Phần theo dõi mô tả cách hoàn tất các bước này.
Nếu phản hồi chứa mã truy cập, bạn có thể sử dụng mã truy cập để gọi API Google. (Nếu phản hồi không bao gồm mã truy cập, yêu cầu mã thông báo và JWT của bạn có thể không được tạo đúng cách hoặc tài khoản dịch vụ có thể không có quyền truy cập vào các phạm vi được yêu cầu.)
Khi mã truy cập hết hạn, ứng dụng sẽ tạo một JWT khác, ký và yêu cầu một mã truy cập khác.

Phần còn lại sẽ mô tả thông tin cụ thể về cách tạo JWT, ký JWT, tạo yêu cầu mã thông báo truy cập và xử lý phản hồi.
Tạo JWT
JWT bao gồm ba phần: tiêu đề, tập xác nhận quyền sở hữu và chữ ký. Tiêu đề và tập hợp 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 phương thức mã hoá Base64url. Phương thức mã hoá này cung cấp khả năng phục hồi trước các thay đổi về mã hoá do các thao tác mã hoá lặp lại. 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 ký tự dấu chấm (.
).
JWT bao gồm:
{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}
Hình thành tiêu đề JWT
Tiêu đề này có 3 trường cho biết thuật toán ký, định dạng câu nhận định và [mã khoá của khoá tài khoản dịch vụ](https://cloud.google.com/iam/docs/reference/rest/v1/projects.serviceAccounts.keys) dùng để ký JWT. Thuật toán và định dạng là bắt buộc và mỗi trường chỉ có một giá trị. Khi các thuật toán và định dạng bổ sung ra mắt, tiêu đề này sẽ thay đổi tương ứng. ID khóa là tùy chọn và nếu ID khóa được chỉ định không chính xác, GCP sẽ thử tất cả các khóa đượ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 khóa hợp lệ. Google có quyền từ chối mã thông báo có mã khoá không chính xác trong tương lai.
Tài khoản dịch vụ dựa vào thuật toán RSA SHA-256 và định dạng mã thông báo JWT. Do đó, cách biểu diễn JSON của tiêu đề như sau:
{"alg":"RS256","typ":"JWT", "kid":"370ab79b4513eb9bad7c9bd16a95cb76b5b2a56a"}
Cách biểu diễn Base64url như sau:
eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCIsICJraWQiOiIzNzBhYjc5YjQ1MTNlYjliYWQ3YzliZDE2YTk1Y2I3NmI1YjJhNTZhIn0=
Hình thành bộ thông báo xác nhận quyền sở hữu JWT
Bộ 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 quyền được yêu cầu (phạm vi), mục tiêu của mã thông báo, tổ chức phát hành, thời gian mã thông báo được phát hành và thời gian tồn tại của mã thông báo. Hầu hết các trường là bắt buộc. Giống như tiêu đề JWT, tập hợp xác nhận quyền sở hữu JWT là một đối tượng JSON và được dùng để tính chữ ký.
Xác nhận quyền sở hữu bắt buộc
Dưới đây là các thông báo xác nhận quyền sở hữu bắt buộc trong tập hợp thông báo xác nhận quyền sở hữu JWT. Các thông báo này có thể xuất hiện theo bất kỳ thứ tự nào trong thông báo xác nhận quyền sở hữu đã đặt.
Tên | Nội dung mô tả |
---|---|
iss |
Địa chỉ email của tài khoản dịch vụ. |
scope |
Danh sách quyền được phân tách bằng dấu cách gồm các quyền mà ứng dụng yêu cầu. |
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, yêu cầu giá trị này luôn là https://oauth2.googleapis.com/token . |
exp |
Thời gian hết hạn của câu nhận định, được chỉ định dưới dạng giây kể từ 00:00:00 giờ UTC, ngày 1 tháng 1 năm 1970. Giá trị này có thời gian 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 dưới dạng giây kể từ 00:00:00 UTC, ngày 1 tháng 1 năm 1970. |
Dưới đây là phần trình bày JSON về các trường bắt buộc trong một bộ 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 }
Khiếu nại bổ sung
Trong một số trường hợp doanh nghiệp, ứng dụng có thể dùng tính năng ủy quyền trên toàn miền để đại diện cho một người dùng cụ thể trong tổ chức. Quyền thực hiện loại 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 do quản trị viên cấp cao xử lý. Để biết thêm thông tin, hãy xem phần Kiểm soát quyền truy cập API thông qua tính năng ủy quyền trên toàn miền.
Để lấy mã truy cập cấp cho ứng dụng quyền truy cập vào một tài nguyên, hãy thêm địa chỉ email của người dùng vào xác nhận quyền sở hữu JWT làm giá trị của trường sub
.
Tên | Nội dung mô tả |
---|---|
sub |
Địa chỉ email của người dùng mà ứng dụng đang yêu cầu quyền truy cập được ủy quyền. |
Nếu một ứng dụng không có quyền mạo danh người dùng, thì phản hồi của yêu cầu mã thông báo truy cập có chứa trường sub
sẽ là một lỗi.
Dưới đây là ví dụ về một thông báo xác nhận quyền sở hữu JWT bao gồm trường sub
:
{ "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ã hóa nhóm xác nhận quyền sở hữu JWT
Giống như tiêu đề JWT, nhóm thông báo xác nhận quyền sở hữu JWT phải được chuyển đổi tuần tự sang UTF-8 và Base64url được mã hóa an toàn. Dưới đây là ví dụ về phần trình bày JSON của một tập hợp 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à thông số 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ý. Thuật toán ký duy nhất được Máy chủ uỷ 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 thể hiện dưới dạng RS256
trong trường 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) bằng khóa riêng tư thu được từ Google API Console. Kết quả sẽ là một mảng byte.
Chữ ký sau đó phải được mã hóa bằng 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 ký tự dấu chấm (.
). Kết quả là JWT. Nội dung này phải như sau (dấu ngắt dòng được thêm vào để làm rõ):
{Base64url encoded header}. {Base64url encoded claim set}. {Base64url encoded signature}
Dưới đây là ví dụ về JWT trước phương thức 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
Thực hiện yêu cầu mã thông báo truy cập
Sau khi tạo JWT đã ký, ứng dụng có thể sử dụng mã này để yêu cầu mã thông báo truy cập.
Yêu cầu mã thông báo truy cập này là yêu cầu HTTPS POST
và nội dung được mã hóa URL. URL được hiển thị bên dưới:
https://oauth2.googleapis.com/token
Các thông số sau đây là bắt buộc trong yêu cầu HTTPS POST
:
Tên | Nội dung mô tả |
---|---|
grant_type |
Sử dụng chuỗi được mã hoá URL nếu cần:
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
dùng trong yêu cầu mã truy cập:
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 mã thông báo truy cập và JWT được tạo đúng cách và tài khoản dịch vụ có quyền thực hiện thao tác, thì phản hồi JSON qua Máy chủ ủy quyền sẽ bao gồm mã truy cập. Dưới đây là phản hồi mẫu:
{ "access_token": "1/8xbJqaOZXSUZbHLl5EOtu1pxz3fmmetKx9W8CV4t79M", "scope": "https://www.googleapis.com/auth/prediction" "token_type": "Bearer", "expires_in": 3600 }
Bạn có thể sử dụng lại mã truy cập trong khoảng thời gian mà giá trị expires_in
chỉ định.
Gọi API Google
Java
Sử dụng đối tượng GoogleCredential
để gọi API Google bằng cách hoàn thành các bước sau:
- 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();
- Thực hiện yêu cầu cho dịch vụ API bằng cách sử dụng giao diện do đối tượng dịch vụ cung cấp.
Ví dụ: để liệt kê các phiên bản của cơ sở dữ liệu Cloud SQL trong dự án thú vị example-123:
SQLAdmin.Instances.List instances = sqladmin.instances().list("exciting-example-123").execute();
Python
Sử dụng đối tượng Credentials
được ủy quyền để gọi các API của Google bằng cách hoàn thành các bước sau:
- 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
có tên và phiên bản của API cũng như đối tượngCredentials
đượ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)
- Thực hiện yêu cầu cho dịch vụ API bằng cách sử dụng giao diện do đối tượng dịch vụ cung cấp.
Ví dụ: để liệt kê các phiên bản của cơ sở dữ liệu Cloud SQL trong dự án thú vị example-123:
response = sqladmin.instances().list(project='exciting-example-123').execute()
HTTP/REST
Sau khi ứng dụng của bạn lấy được mã truy cập, bạn có thể sử dụng mã thông báo này để thực hiện lệnh gọi đến API Google thay mặt cho một tài khoản dịch vụ hoặc tài khoản người dùng cụ thể 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 đưa mã truy cập vào một yêu cầu tới API bằng cách đưa vào một tham số truy vấn access_token
hoặc một giá trị Bearer
tiêu đề HTTP Authorization
. Khi có thể, bạn nên ưu tiên tiêu đề HTTP hơn vì các chuỗi truy vấn thường hiển thị trong nhật ký máy chủ. Trong hầu hết trường hợp, 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 tại OAuth 2.0 Playground.
Ví dụ về HTTP GET
Lệnh gọi đến điểm cuối
drive.files
(API Tệp Drive) bằng tiêu đề 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 đã xác thực bằng cách sử dụng tham số chuỗi truy vấn access_token
:
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
. Dưới đây là ví dụ về cách 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, có thể là, tùy chọn tham số chuỗi truy vấn:
curl https://www.googleapis.com/drive/v2/files?access_token=access_token
Khi mã thông báo truy cập hết hạn
Mã thông báo truy cập do Máy chủ uỷ quyền OAuth 2.0 của Google 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, ứng dụng sẽ tạo một JWT khác, ký và yêu cầu một mã truy cập khác.
Mã lỗi JWT
Trường error |
Trường error_description |
Ý 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 ủy quyền trên toàn miền, thì tài khoản dịch vụ này không được phép 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 đó. |
Đảm bảo rằng tài khoản dịch vụ đã được uỷ quyền trong trang
Ủy quyền trên toàn miền của Bảng điều khiển dành cho quản trị viên của người dùng trong thông báo xác nhận quyền sở hữu của Mặc dù thường mất vài phút, nhưng cũng có trường hợp mất đến 24 giờ để việc cấp phép mới được á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. |
Tài khoản dịch vụ đã được cấp phép bằng địa chỉ email của khách hàng chứ không phải mã ứng dụng (chữ số) trong Bảng điều khiển dành cho quản trị viên. | Trên trang Ủy 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 xóa rồi thêm lại mã khách hàng bằng mã số. |
access_denied |
(giá trị bất kỳ) | Nếu bạn đang sử dụng tính năng ủy quyền trên toàn miền, thì một hoặc nhiều phạm vi yêu cầu sẽ không được cấp phép trong Bảng điều khiển dành cho quản trị viên. |
Đảm bảo rằng tài khoản dịch vụ đã được uỷ quyền trong trang
Ủy quyền trên toàn miền của Bảng điều khiển dành cho quản trị viên của người dùng trong thông báo xác nhận quyền sở hữu của Mặc dù thường mất vài phút, nhưng cũng có trường hợp mất đến 24 giờ để việc cấp phép mới được á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ể ủy quyền cho một hoặc nhiều phạm vi được yêu cầu do các chính sách của quản trị viên Google Workspace. |
Hãy xem bài viết trợ giúp dành cho Quản trị viên Google Workspace Kiểm soát những ứng dụng nội bộ và ứng dụng nội bộ có quyền truy cập vào dữ liệu trên 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 vào mọi phạm vi hoặc phạm vi nhạy cảm và bị hạn chế cho đến khi bạn cấp quyền truy cập rõ ràng cho mã ứng dụng khách OAuth. |
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. Tham khảo mô tả lỗi để biết 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 xem tài khoản ứng dụng khách và dịch vụ OAuth có được định cấu hình chính xác hay không và bạn có đang sử dụng đúng địa chỉ email hay không. Kiểm tra xem mã thông báo JWT có chính xác và được cấp cho mã ứng dụng khách trong yêu cầu hay không. |
invalid_grant |
Not a valid email. |
Người dùng không tồn tại. | Kiểm tra xem địa chỉ email trong trường sub (trường) đã chính xác chưa. |
invalid_grant |
|
Thông thường, điều đó có nghĩa là giờ địa phương của hệ thống không chính xác. Điều này cũng có thể xảy ra nếu giá trị exp sau hơn 65 phút kể từ giá trị iat hoặc giá trị exp thấp hơn giá trị iat . |
Đả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 cần, hãy đồng bộ hóa thời gian của bạn với Google NTP. |
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 qua email khách hàng hoặc khoá được dùng đã bị xoá, vô hiệu hoá hoặc đã hết hạn. Ngoài ra, lời khẳng định JWT có thể được mã hóa không chính xác – phải được mã hóa bằng Base64, không có dòng mới hoặc dấu hiệu đệm bằng nhau. |
Giải mã thông báo xác nhận quyền sở hữu JWT rồi xác minh khóa đã ký xác nhận được liên kết với tài khoản dịch vụ. Hãy thử sử dụng thư viện OAuth do Google cung cấp để đảm bảo tạo JWT chính xác. |
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 Xin lưu ý rằng danh sách các phạm vi trong thông báo xác nhận quyền sở hữu |
disabled_client |
The OAuth client was disabled. |
Khóa dùng để ký xác nhận JWT đã bị tắt. |
Đi tới Google API Consolevà trong IAM & Admin > Tài khoản dịch vụ, hãy bật tài khoản dịch vụ chứa "Mã khoá" dùng để ký xác nhận. |
org_internal |
This client is restricted to users within its organization. |
Mã ứng dụng OAuth trong yêu cầu này là một phần của dự án hạn chế quyền truy cập vào Tài khoản Google trong một tổ chức cụ thể của Google Cloud. |
Sử dụng tài khoản dịch vụ của tổ chức để xác thực. Xác nhận cấu hình loại người dùng cho ứng dụng OAuth. |
Phụ lục: Ủy 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 ủy quyền bằng cách 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 phải gửi yêu cầu mạng đến 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 dịch vụ được phát hành trong kho lưu trữ Google API GitHub, bạn có thể thực hiện các lệnh gọi API được ủy quyền bằng JWT thay vì mã thông báo truy cập. Cách làm như sau:
- Tạo một tài khoản dịch vụ như mô tả ở trên. Hãy nhớ giữ tệp JSON mà bạn nhận được khi tạo tài khoản.
- Sử dụng bất kỳ thư viện JWT chuẩn nào, chẳng hạn như thư viện tại jwt.io, tạo một JWT có tiêu đề và trọng tải như 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 mã khoá riêng tư của tài khoản dịch vụ. Bạn có thể tìm giá trị này trong trườngprivate_key_id
của tệp JSON tài khoản dịch vụ. - Đối với các trường
iss
vàsub
, hãy chỉ định địa chỉ email của tài khoản dịch vụ. Bạn có thể tìm giá trị này trong trườngclient_email
của tệp JSON cho tài khoản dịch vụ. - Đối với trường
aud
, hãy chỉ định điểm cuối 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à trong trườngexp
, hãy chỉ định thời gian chính xác là 3600 giây sau, khi JWT 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-client và java-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')
- Gọi API, sử dụng JWT đã ký làm mã thông báo truy cập:
GET /v1/projects/abc/databases/123/indexes HTTP/1.1 Authorization: Bearer SIGNED_JWT Host: firestore.googleapis.com