Tài liệu này giải thích cách các ứng dụng máy chủ web sử dụng Thư viện ứng dụng API của Google hoặc điểm cuối Google OAuth 2.0 để triển khai việc cấp quyền OAuth 2.0 để truy cập vào các API của Google.
OAuth 2.0 cho phép người dùng chia sẻ dữ liệu cụ thể với một ứng dụng mà vẫn giữ bí mật tên người dùng, mật khẩu và các thông tin khác. Ví dụ: một ứng dụng có thể sử dụng OAuth 2.0 để có được quyền của người dùng khi lưu trữ tệp trong Google Drive của họ.
Quy trình OAuth 2.0 này dành riêng cho việc ủy quyền cho người dùng. API này được thiết kế cho các ứng dụng có thể lưu trữ thông tin mật và duy trì trạng thái. Ứng dụng máy chủ web được uỷ quyền đúng cách có thể truy cập vào API trong khi người dùng tương tác với ứng dụng hoặc sau khi người dùng rời khỏi ứng dụng.
Các ứng dụng máy chủ web cũng thường sử dụng tài khoản dịch vụ để cho phép các yêu cầu API, đặc biệt là khi gọi Cloud API để truy cập dữ liệu dựa trên dự án thay vì dữ liệu riêng cho người dùng. Các ứng dụng máy chủ web có thể sử dụng tài khoản dịch vụ cùng với việc uỷ quyền cho người dùng.
Thư viện ứng dụng
Các ví dụ về ngôn ngữ cụ thể trên trang này sử dụng Thư viện ứng dụng API của Google để triển khai lệnh ủy quyền OAuth 2.0. Để chạy mã mẫu, trước tiên, bạn phải cài đặt thư viện ứng dụng cho ngôn ngữ của mình.
Khi bạn sử dụng Thư viện ứng dụng API của Google để xử lý luồng OAuth 2.0 của ứng dụng, thư viện ứng dụng sẽ thực hiện nhiều thao tác mà ứng dụng cần tự xử lý. Ví dụ: Thông tin này xác định thời điểm ứng dụng có thể sử dụng hoặc làm mới mã thông báo truy cập đã lưu trữ cũng như thời điểm ứng dụng phải lấy lại sự đồng ý. Thư viện ứng dụng cũng tạo đúng URL chuyển hướng và giúp triển khai trình xử lý chuyển hướng trao đổi mã uỷ quyền cho mã truy cập.
Thư viện ứng dụng API của Google cho các ứng dụng phía máy chủ có sẵn cho các ngôn ngữ sau:
Điều kiện tiên quyết
Bật API cho dự án
Bất kỳ ứng dụng nào gọi API của Google đều phải bật các API đó trong API Console.
Cách bật API cho dự án:
- Open the API Library trong Google API Console.
- If prompted, select a project, or create a new one.
- API Library Liệt kê tất cả các API có sẵn, được nhóm theo nhóm sản phẩm và mức độ phổ biến. Nếu API bạn muốn chọn không hiển thị trong danh sách, hãy sử dụng chức năng tìm kiếm để tìm API đó hoặc nhấp vào Xem tất cả trong nhóm sản phẩm chứa API đó.
- Chọn API bạn muốn bật, sau đó nhấp vào nút Bật.
- If prompted, enable billing.
- If prompted, read and accept the API's Terms of Service.
Tạo thông tin cấp phép
Bất kỳ ứng dụng nào dùng OAuth 2.0 để truy cập API của Google đều phải có thông tin xác thực ủy quyền giúp xác định ứng dụng đó với máy chủ OAuth 2.0 của Google. Các bước sau giải thích cách tạo thông tin xác thực cho dự án của bạn. Sau đó, các ứng dụng của bạn có thể dùng thông tin xác thực để truy cập vào những API mà bạn đã bật cho dự án đó.
- Go to the Credentials page.
- Nhấp vào Tạo thông tin xác thực > Mã ứng dụng khách OAuth.
- Chọn loại ứng dụng Ứng dụng web.
- Điền vào biểu mẫu rồi nhấp vào Tạo. Các ứng dụng dùng ngôn ngữ và khung như PHP, Java, Python, Ruby và .NET phải chỉ định các URI chuyển hướng được phép. URI chuyển hướng là các điểm cuối mà máy chủ OAuth 2.0 có thể gửi phản hồi. Các điểm cuối này phải tuân thủ các quy tắc xác thực của Google.
Để kiểm thử, bạn có thể chỉ định URI tham chiếu đến máy cục bộ, chẳng hạn như
http://localhost:8080
. Vì vậy, hãy lưu ý rằng tất cả ví dụ trong tài liệu này đều sử dụnghttp://localhost:8080
làm URI chuyển hướng.Bạn nên thiết kế điểm cuối xác thực của ứng dụng để ứng dụng không hiển thị mã uỷ quyền cho các tài nguyên khác trên trang.
Sau khi tạo thông tin xác thực, hãy tải tệp client_secret.json xuống từ API Console. Lưu trữ tệp một cách an toàn ở vị trí mà chỉ ứng dụng của bạn mới có thể truy cập.
Xác định phạm vi truy cập
Phạm vi cho phép ứng dụng của bạn chỉ yêu cầu quyền truy cập vào các tài nguyên cần thiết, đồng thời cho phép người dùng kiểm soát số lượng quyền truy cập mà họ cấp cho ứng dụng của bạn. Do đó, có thể có mối quan hệ nghịch đảo giữa số lượng phạm vi được yêu cầu và khả năng đạt được sự đồng ý của người dùng.
Trước khi bắt đầu triển khai lệnh ủy quyền OAuth 2.0, bạn nên xác định các phạm vi mà ứng dụng của bạn cần có quyền truy cập.
Ứng dụng cũng nên yêu cầu quyền truy cập vào phạm vi uỷ quyền thông qua quy trình uỷ quyền gia tăng, trong đó ứng dụng yêu cầu quyền truy cập vào dữ liệu người dùng trong ngữ cảnh. Phương pháp hay nhất này giúp người dùng dễ dàng hiểu được lý do ứng dụng của bạn cần quyền truy cập mà ứng dụng đó yêu cầu.
Tài liệu về Phạm vi API OAuth 2.0 chứa danh sách đầy đủ các phạm vi mà bạn có thể sử dụng để truy cập vào API của Google.
Yêu cầu dành riêng cho từng ngôn ngữ
Để chạy bất kỳ mã mẫu nào trong tài liệu này, bạn sẽ cần có một Tài khoản Google, quyền truy cập vào Internet và trình duyệt web. Nếu bạn đang sử dụng một trong những thư viện ứng dụng API, hãy xem các yêu cầu về ngôn ngữ cụ thể bên dưới.
PHP
Để chạy các mã mẫu PHP trong tài liệu này, bạn sẽ cần:
- PHP 5.6 trở lên có cài đặt giao diện dòng lệnh (CLI) và tiện ích JSON.
- Công cụ quản lý phần phụ thuộc Composer.
-
Thư viện ứng dụng API cho Google API:
composer require google/apiclient:^2.10
Python
Để chạy các mã mẫu Python trong tài liệu này, bạn cần:
- Python từ 2.6 trở lên
- Công cụ quản lý gói pip.
- Thư viện ứng dụng Python cho API của Google:
pip install --upgrade google-api-python-client
google-auth
,google-auth-oauthlib
vàgoogle-auth-httplib2
để cho phép người dùng.pip install --upgrade google-auth google-auth-oauthlib google-auth-httplib2
- Khung ứng dụng web Flask Python.
pip install --upgrade flask
- Thư viện HTTP
requests
.pip install --upgrade requests
Ruby
Để chạy các mẫu mã Ruby trong tài liệu này, bạn cần:
- Ruby 2.2.2 trở lên
-
Thư viện ứng dụng API của Google cho Ruby:
gem install google-api-client
-
Khung ứng dụng web Sinatra Ruby.
gem install sinatra
Node.js
Để chạy các mã mẫu Node.js trong tài liệu này, bạn cần:
- Việc bảo trì LTS, LTS đang hoạt động hoặc bản phát hành hiện tại của Node.js.
-
Ứng dụng Node.js của các API của Google:
npm install googleapis
HTTP/REST (Hệ thống HTTP/REST)
Bạn không cần cài đặt bất kỳ thư viện nào để có thể gọi trực tiếp các điểm cuối OAuth 2.0.
Lấy mã truy cập OAuth 2.0
Các bước sau đây cho thấy cách ứng dụng của bạn tương tác với máy chủ OAuth 2.0 của Google để có được sự đồng ý của người dùng thay mặt người dùng thực hiện API. Ứng dụng của bạn phải có được sự đồng ý đó trước khi có thể thực thi một yêu cầu API của Google có yêu cầu người dùng phải uỷ quyền.
Danh sách dưới đây tóm tắt nhanh các bước sau:
- Ứng dụng của bạn xác định các quyền cần thiết.
- Ứng dụng của bạn chuyển hướng người dùng đến Google cùng với danh sách các quyền được yêu cầu.
- Người dùng quyết định việc có cấp quyền cho ứng dụng của bạn hay không.
- Ứng dụng của bạn tìm hiểu xem người dùng đã quyết định điều gì.
- Nếu người dùng đã cấp các quyền được yêu cầu, thì ứng dụng của bạn sẽ truy xuất các mã thông báo cần thiết để thay mặt người dùng yêu cầu API.
Bước 1: Đặt thông số uỷ quyền
Bước đầu tiên là tạo yêu cầu uỷ quyền. Yêu cầu đó đặt các tham số xác định ứng dụng và xác định các quyền mà người dùng sẽ được yêu cầu cấp cho ứng dụng.
- Nếu sử dụng một thư viện ứng dụng Google để xác thực và ủy quyền OAuth 2.0, bạn sẽ tạo và định cấu hình một đối tượng sẽ xác định các tham số này.
- Nếu gọi trực tiếp điểm cuối Google OAuth 2.0, bạn sẽ tạo một URL và đặt tham số trên URL đó.
Các thẻ dưới đây xác định các thông số uỷ quyền được hỗ trợ cho các ứng dụng máy chủ web. Các ví dụ về ngôn ngữ cụ thể cũng cho thấy cách sử dụng thư viện ứng dụng hoặc thư viện ủy quyền để định cấu hình một đối tượng đặt các tham số đó.
PHP
Đoạn mã dưới đây sẽ tạo một đối tượng Google\Client()
, sẽ xác định
các tham số trong yêu cầu uỷ quyền.
Đối tượng đó sử dụng thông tin từ tệp client_secret.json để xác định ứng dụng của bạn. (Xem cách tạo thông tin uỷ quyền để biết thêm thông tin về tệp đó.) Đối tượng cũng xác định các phạm vi mà ứng dụng của bạn đang yêu cầu quyền truy cập và URL đến điểm cuối xác thực của ứng dụng. Điểm cuối này sẽ xử lý phản hồi từ máy chủ OAuth 2.0 của Google. Cuối cùng, mã này sẽ đặt các thông số access_type
và include_granted_scopes
(không bắt buộc).
Ví dụ: mã này yêu cầu quyền truy cập ngoại tuyến, chỉ đọc vào Google Drive của người dùng:
$client = new Google\Client(); $client->setAuthConfig('client_secret.json'); $client->addScope(Google\Service\Drive::DRIVE_METADATA_READONLY); $client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php'); // offline access will give you both an access and refresh token so that // your app can refresh the access token without user interaction. $client->setAccessType('offline'); // Using "consent" ensures that your application always receives a refresh token. // If you are not using offline access, you can omit this. $client->setApprovalPrompt('consent'); $client->setIncludeGrantedScopes(true); // incremental auth
Yêu cầu này chỉ định những thông tin sau:
Các tham số | |||||||
---|---|---|---|---|---|---|---|
client_id |
Bắt buộc
Mã ứng dụng khách cho ứng dụng của bạn. Bạn có thể tìm thấy giá trị này trong API Console Credentials page. Trong PHP, hãy gọi hàm $client = new Google\Client(); $client->setAuthConfig('client_secret.json'); |
||||||
redirect_uri |
Bắt buộc
Xác định vị trí máy chủ API chuyển hướng người dùng sau khi người dùng hoàn tất quy trình uỷ quyền. Giá trị này phải khớp chính xác với một trong các URI chuyển hướng được uỷ quyền cho ứng dụng OAuth 2.0, mà bạn đã định cấu hình trong API Consolecủa Credentials pagecho ứng dụng. Nếu giá trị này không khớp với URI chuyển hướng được uỷ quyền cho Xin lưu ý rằng giao thức Để đặt giá trị này trong PHP, hãy gọi hàm $client->setRedirectUri('https://oauth2.example.com/code'); |
||||||
scope |
Bắt buộc
Danh sách các phạm vi phân tách bằng dấu cách xác định các tài nguyên mà ứng dụng của bạn có thể thay mặt người dùng truy cập. Những giá trị này thông báo cho người dùng về màn hình xin phép mà Google hiển thị. Phạm vi cho phép ứng dụng của bạn chỉ yêu cầu quyền truy cập vào các tài nguyên cần thiết, đồng thời cho phép người dùng kiểm soát số lượng quyền truy cập mà họ cấp vào ứng dụng của bạn. Do đó, có một mối tương quan nghịch giữa số lượng phạm vi được yêu cầu và khả năng nhận được sự đồng ý của người dùng. Để đặt giá trị này trong PHP, hãy gọi hàm $client->addScope(Google\Service\Drive::DRIVE_METADATA_READONLY); Ứng dụng của bạn nên có quyền truy cập vào phạm vi uỷ quyền trong ngữ cảnh bất cứ khi nào có thể. Bằng cách yêu cầu quyền truy cập vào dữ liệu người dùng trong ngữ cảnh, thông qua sự ủy quyền gia tăng, bạn giúp người dùng dễ dàng hiểu được lý do ứng dụng của bạn cần quyền truy cập như yêu cầu. |
||||||
access_type |
Nên
Cho biết liệu ứng dụng của bạn có thể làm mới mã thông báo truy cập khi người dùng không có mặt trên trình duyệt hay không. Các giá trị tham số hợp lệ là Đặt giá trị thành Để đặt giá trị này trong PHP, hãy gọi hàm $client->setAccessType('offline'); |
||||||
state |
Nên
Chỉ định mọi giá trị chuỗi mà ứng dụng sử dụng để duy trì trạng thái giữa yêu cầu uỷ quyền và phản hồi của máy chủ uỷ quyền.
Máy chủ trả về giá trị chính xác mà bạn gửi dưới dạng một cặp Bạn có thể sử dụng tham số này cho một số mục đích, chẳng hạn như hướng người dùng đến đúng tài nguyên trong ứng dụng, gửi số chỉ dùng một lần và giảm thiểu yêu cầu giả mạo trên nhiều trang web. Vì Để đặt giá trị này trong PHP, hãy gọi hàm $client->setState($sample_passthrough_value); |
||||||
include_granted_scopes |
Optional (Không bắt buộc)
Cho phép các ứng dụng sử dụng chế độ ủy quyền gia tăng để yêu cầu quyền truy cập vào
các phạm vi bổ sung trong ngữ cảnh. Nếu bạn đặt giá trị của tham số này thành Để đặt giá trị này trong PHP, hãy gọi hàm $client->setIncludeGrantedScopes(true); |
||||||
login_hint |
Optional (Không bắt buộc)
Nếu biết người dùng nào đang cố gắng xác thực, thì ứng dụng của bạn có thể sử dụng thông số này để cung cấp gợi ý cho Máy chủ xác thực của Google. Máy chủ sử dụng gợi ý để đơn giản hoá quy trình đăng nhập bằng cách điền sẵn trường email vào biểu mẫu đăng nhập, hoặc chọn phiên đăng nhập nhiều tài khoản thích hợp. Đặt giá trị tham số thành địa chỉ email hoặc giá trị nhận dạng Để đặt giá trị này trong PHP, hãy gọi hàm $client->setLoginHint('None'); |
||||||
prompt |
Optional (Không bắt buộc)
Danh sách lời nhắc phân biệt chữ hoa chữ thường, phân tách bằng dấu cách để trình bày cho người dùng. Nếu bạn không chỉ định thông số này, thì người dùng sẽ chỉ được nhắc trong lần đầu tiên dự án của bạn yêu cầu quyền truy cập. Hãy xem bài viết Lời nhắc nhắc lại sự đồng ý để biết thêm thông tin. Để đặt giá trị này trong PHP, hãy gọi hàm $client->setApprovalPrompt('consent'); Các giá trị có thể là:
|
Python
Đoạn mã sau đây sử dụng mô-đun google-auth-oauthlib.flow
để tạo
yêu cầu uỷ quyền.
Mã này tạo một đối tượng Flow
giúp xác định ứng dụng của bạn bằng cách sử dụng thông tin từ tệp client_secret.json mà bạn đã tải xuống sau khi tạo thông tin xác thực ủy quyền. Đối tượng đó cũng xác định các phạm vi mà ứng dụng của bạn đang yêu cầu quyền truy cập và URL dẫn đến điểm cuối xác thực của ứng dụng. Điểm cuối này sẽ xử lý phản hồi từ máy chủ OAuth 2.0 của Google. Cuối cùng, mã này
sẽ đặt các thông số access_type
và include_granted_scopes
(không bắt buộc).
Ví dụ: mã này yêu cầu quyền truy cập ngoại tuyến, chỉ đọc vào Google Drive của người dùng:
import google.oauth2.credentials import google_auth_oauthlib.flow # Use the client_secret.json file to identify the application requesting # authorization. The client ID (from that file) and access scopes are required. flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( 'client_secret.json', scopes=['https://www.googleapis.com/auth/drive.metadata.readonly']) # Indicate where the API server will redirect the user after the user completes # the authorization flow. The redirect URI is required. The value must exactly # match one of the authorized redirect URIs for the OAuth 2.0 client, which you # configured in the API Console. If this value doesn't match an authorized URI, # you will get a 'redirect_uri_mismatch' error. flow.redirect_uri = 'https://www.example.com/oauth2callback' # Generate URL for request to Google's OAuth 2.0 server. # Use kwargs to set optional request parameters. authorization_url, state = flow.authorization_url( # Enable offline access so that you can refresh an access token without # re-prompting the user for permission. Recommended for web server apps. access_type='offline', # Enable incremental authorization. Recommended as a best practice. include_granted_scopes='true')
Yêu cầu này chỉ định những thông tin sau:
Các tham số | |||||||
---|---|---|---|---|---|---|---|
client_id |
Bắt buộc
Mã ứng dụng khách cho ứng dụng của bạn. Bạn có thể tìm thấy giá trị này trong API Console Credentials page. Trong Python, hãy gọi phương thức flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( 'client_secret.json', scopes=['https://www.googleapis.com/auth/drive.metadata.readonly']) |
||||||
redirect_uri |
Bắt buộc
Xác định vị trí máy chủ API chuyển hướng người dùng sau khi người dùng hoàn tất quy trình uỷ quyền. Giá trị này phải khớp chính xác với một trong các URI chuyển hướng được uỷ quyền cho ứng dụng OAuth 2.0, mà bạn đã định cấu hình trong API Consolecủa Credentials pagecho ứng dụng. Nếu giá trị này không khớp với URI chuyển hướng được uỷ quyền cho Xin lưu ý rằng giao thức Để đặt giá trị này trong Python, hãy đặt thuộc tính flow.redirect_uri = 'https://oauth2.example.com/code' |
||||||
scope |
Bắt buộc
Danh sách phạm vi xác định tài nguyên mà ứng dụng của bạn có thể thay mặt người dùng truy cập. Những giá trị này thông báo cho người dùng về màn hình xin phép mà Google hiển thị. Phạm vi cho phép ứng dụng của bạn chỉ yêu cầu quyền truy cập vào các tài nguyên cần thiết, đồng thời cho phép người dùng kiểm soát số lượng quyền truy cập mà họ cấp vào ứng dụng của bạn. Do đó, có một mối tương quan nghịch giữa số lượng phạm vi được yêu cầu và khả năng nhận được sự đồng ý của người dùng. Trong Python, hãy sử dụng cùng một phương thức mà bạn sử dụng để đặt flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( 'client_secret.json', scopes=['https://www.googleapis.com/auth/drive.metadata.readonly']) Ứng dụng của bạn nên có quyền truy cập vào phạm vi uỷ quyền trong ngữ cảnh bất cứ khi nào có thể. Bằng cách yêu cầu quyền truy cập vào dữ liệu người dùng trong ngữ cảnh, thông qua sự ủy quyền gia tăng, bạn giúp người dùng dễ dàng hiểu được lý do ứng dụng của bạn cần quyền truy cập như yêu cầu. |
||||||
access_type |
Nên
Cho biết liệu ứng dụng của bạn có thể làm mới mã thông báo truy cập khi người dùng không có mặt trên trình duyệt hay không. Các giá trị tham số hợp lệ là Đặt giá trị thành Trong Python, hãy đặt tham số authorization_url, state = flow.authorization_url( access_type='offline', include_granted_scopes='true') |
||||||
state |
Nên
Chỉ định mọi giá trị chuỗi mà ứng dụng sử dụng để duy trì trạng thái giữa yêu cầu uỷ quyền và phản hồi của máy chủ uỷ quyền.
Máy chủ trả về giá trị chính xác mà bạn gửi dưới dạng một cặp Bạn có thể sử dụng tham số này cho một số mục đích, chẳng hạn như hướng người dùng đến đúng tài nguyên trong ứng dụng, gửi số chỉ dùng một lần và giảm thiểu yêu cầu giả mạo trên nhiều trang web. Vì Trong Python, hãy đặt tham số authorization_url, state = flow.authorization_url( access_type='offline', state=sample_passthrough_value, include_granted_scopes='true') |
||||||
include_granted_scopes |
Optional (Không bắt buộc)
Cho phép các ứng dụng sử dụng chế độ ủy quyền gia tăng để yêu cầu quyền truy cập vào
các phạm vi bổ sung trong ngữ cảnh. Nếu bạn đặt giá trị của tham số này thành Trong Python, hãy đặt tham số authorization_url, state = flow.authorization_url( access_type='offline', include_granted_scopes='true') |
||||||
login_hint |
Optional (Không bắt buộc)
Nếu biết người dùng nào đang cố gắng xác thực, thì ứng dụng của bạn có thể sử dụng thông số này để cung cấp gợi ý cho Máy chủ xác thực của Google. Máy chủ sử dụng gợi ý để đơn giản hoá quy trình đăng nhập bằng cách điền sẵn trường email vào biểu mẫu đăng nhập, hoặc chọn phiên đăng nhập nhiều tài khoản thích hợp. Đặt giá trị tham số thành địa chỉ email hoặc giá trị nhận dạng Trong Python, hãy đặt tham số authorization_url, state = flow.authorization_url( access_type='offline', login_hint='None', include_granted_scopes='true') |
||||||
prompt |
Optional (Không bắt buộc)
Danh sách lời nhắc phân biệt chữ hoa chữ thường, phân tách bằng dấu cách để trình bày cho người dùng. Nếu bạn không chỉ định thông số này, thì người dùng sẽ chỉ được nhắc trong lần đầu tiên dự án của bạn yêu cầu quyền truy cập. Hãy xem bài viết Lời nhắc nhắc lại sự đồng ý để biết thêm thông tin. Trong Python, hãy đặt tham số authorization_url, state = flow.authorization_url( access_type='offline', prompt='consent', include_granted_scopes='true') Các giá trị có thể là:
|
Ruby
Sử dụng tệp client_secrets.json mà bạn đã tạo để định cấu hình một đối tượng ứng dụng trong ứng dụng của mình. Khi định cấu hình một đối tượng ứng dụng khách, bạn chỉ định các phạm vi mà ứng dụng của bạn cần truy cập, cùng với URL dẫn đến điểm cuối xác thực của ứng dụng. Điểm cuối này sẽ xử lý phản hồi từ máy chủ OAuth 2.0.
Ví dụ: mã này yêu cầu quyền truy cập ngoại tuyến, chỉ đọc vào Google Drive của người dùng:
require 'google/apis/drive_v2' require 'google/api_client/client_secrets' client_secrets = Google::APIClient::ClientSecrets.load auth_client = client_secrets.to_authorization auth_client.update!( :scope => 'https://www.googleapis.com/auth/drive.metadata.readonly', :redirect_uri => 'http://www.example.com/oauth2callback', :additional_parameters => { "access_type" => "offline", # offline access "include_granted_scopes" => "true" # incremental auth } )
Ứng dụng của bạn dùng đối tượng ứng dụng khách để thực hiện các thao tác OAuth 2.0, chẳng hạn như tạo URL yêu cầu uỷ quyền và áp dụng mã truy cập cho các yêu cầu HTTP.
Node.js
Đoạn mã dưới đây sẽ tạo một đối tượng google.auth.OAuth2
, sẽ xác định
các tham số trong yêu cầu uỷ quyền.
Đối tượng đó sử dụng thông tin từ tệp client_secret.json để xác định ứng dụng của bạn. Để yêu cầu người dùng cấp quyền truy xuất mã thông báo truy cập, bạn sẽ chuyển hướng họ đến trang đồng ý. Cách tạo URL của trang đồng ý:
const {google} = require('googleapis'); /** * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI * from the client_secret.json file. To get these credentials for your application, visit * https://console.cloud.google.com/apis/credentials. */ const oauth2Client = new google.auth.OAuth2( YOUR_CLIENT_ID, YOUR_CLIENT_SECRET, YOUR_REDIRECT_URL ); // Access scopes for read-only Drive activity. const scopes = [ 'https://www.googleapis.com/auth/drive.metadata.readonly' ]; // Generate a url that asks permissions for the Drive activity scope const authorizationUrl = oauth2Client.generateAuthUrl({ // 'online' (default) or 'offline' (gets refresh_token) access_type: 'offline', /** Pass in the scopes array defined above. * Alternatively, if only one scope is needed, you can pass a scope URL as a string */ scope: scopes, // Enable incremental authorization. Recommended as a best practice. include_granted_scopes: true });
Lưu ý quan trọng – refresh_token
chỉ được trả về trong lần uỷ quyền đầu tiên. Tìm hiểu thêm
tại đây.
HTTP/REST (Hệ thống HTTP/REST)
Điểm cuối OAuth 2.0 của Google nằm tại https://accounts.google.com/o/oauth2/v2/auth
. Bạn chỉ có thể truy cập điểm cuối này qua HTTPS. Kết nối HTTP thuần tuý bị từ chối.
Máy chủ uỷ quyền của Google hỗ trợ các tham số chuỗi truy vấn sau đây đối với các ứng dụng máy chủ web:
Các tham số | |||||||
---|---|---|---|---|---|---|---|
client_id |
Bắt buộc
Mã ứng dụng khách cho ứng dụng của bạn. Bạn có thể tìm thấy giá trị này trong API Console Credentials page. |
||||||
redirect_uri |
Bắt buộc
Xác định vị trí máy chủ API chuyển hướng người dùng sau khi người dùng hoàn tất quy trình uỷ quyền. Giá trị này phải khớp chính xác với một trong các URI chuyển hướng được uỷ quyền cho ứng dụng OAuth 2.0, mà bạn đã định cấu hình trong API Consolecủa Credentials pagecho ứng dụng. Nếu giá trị này không khớp với URI chuyển hướng được uỷ quyền cho Xin lưu ý rằng giao thức |
||||||
response_type |
Bắt buộc
Xác định xem điểm cuối Google OAuth 2.0 có trả về mã uỷ quyền hay không. Đặt giá trị thông số thành |
||||||
scope |
Bắt buộc
Danh sách các phạm vi phân tách bằng dấu cách xác định các tài nguyên mà ứng dụng của bạn có thể thay mặt người dùng truy cập. Những giá trị này thông báo cho người dùng về màn hình xin phép mà Google hiển thị. Phạm vi cho phép ứng dụng của bạn chỉ yêu cầu quyền truy cập vào các tài nguyên cần thiết, đồng thời cho phép người dùng kiểm soát số lượng quyền truy cập mà họ cấp vào ứng dụng của bạn. Do đó, có một mối tương quan nghịch giữa số lượng phạm vi được yêu cầu và khả năng nhận được sự đồng ý của người dùng. Ứng dụng của bạn nên có quyền truy cập vào phạm vi uỷ quyền trong ngữ cảnh bất cứ khi nào có thể. Bằng cách yêu cầu quyền truy cập vào dữ liệu người dùng trong ngữ cảnh, thông qua sự ủy quyền gia tăng, bạn giúp người dùng dễ dàng hiểu được lý do ứng dụng của bạn cần quyền truy cập như yêu cầu. |
||||||
access_type |
Nên
Cho biết liệu ứng dụng của bạn có thể làm mới mã thông báo truy cập khi người dùng không có mặt trên trình duyệt hay không. Các giá trị tham số hợp lệ là Đặt giá trị thành |
||||||
state |
Nên
Chỉ định mọi giá trị chuỗi mà ứng dụng sử dụng để duy trì trạng thái giữa yêu cầu uỷ quyền và phản hồi của máy chủ uỷ quyền.
Máy chủ trả về giá trị chính xác mà bạn gửi dưới dạng một cặp Bạn có thể sử dụng tham số này cho một số mục đích, chẳng hạn như hướng người dùng đến đúng tài nguyên trong ứng dụng, gửi số chỉ dùng một lần và giảm thiểu yêu cầu giả mạo trên nhiều trang web. Vì |
||||||
include_granted_scopes |
Optional (Không bắt buộc)
Cho phép các ứng dụng sử dụng chế độ ủy quyền gia tăng để yêu cầu quyền truy cập vào
các phạm vi bổ sung trong ngữ cảnh. Nếu bạn đặt giá trị của tham số này thành |
||||||
login_hint |
Optional (Không bắt buộc)
Nếu biết người dùng nào đang cố gắng xác thực, thì ứng dụng của bạn có thể sử dụng thông số này để cung cấp gợi ý cho Máy chủ xác thực của Google. Máy chủ sử dụng gợi ý để đơn giản hoá quy trình đăng nhập bằng cách điền sẵn trường email vào biểu mẫu đăng nhập, hoặc chọn phiên đăng nhập nhiều tài khoản thích hợp. Đặt giá trị tham số thành địa chỉ email hoặc giá trị nhận dạng |
||||||
prompt |
Optional (Không bắt buộc)
Danh sách lời nhắc phân biệt chữ hoa chữ thường, phân tách bằng dấu cách để trình bày cho người dùng. Nếu bạn không chỉ định thông số này, thì người dùng sẽ chỉ được nhắc trong lần đầu tiên dự án của bạn yêu cầu quyền truy cập. Hãy xem bài viết Lời nhắc nhắc lại sự đồng ý để biết thêm thông tin. Các giá trị có thể là:
|
Bước 2: Chuyển hướng đến máy chủ OAuth 2.0 của Google
Chuyển hướng người dùng đến máy chủ OAuth 2.0 của Google để bắt đầu quy trình xác thực và uỷ quyền. Thông thường, điều này xảy ra khi ứng dụng của bạn cần truy cập vào dữ liệu của người dùng trước tiên. Trong trường hợp uỷ quyền gia tăng, bước này cũng xảy ra khi trước tiên ứng dụng của bạn cần truy cập vào các tài nguyên bổ sung mà ứng dụng chưa có quyền truy cập.
PHP
- Tạo URL để yêu cầu quyền truy cập từ máy chủ OAuth 2.0 của Google:
$auth_url = $client->createAuthUrl();
- Chuyển hướng người dùng đến
$auth_url
:header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL));
Python
Ví dụ này cho thấy cách chuyển hướng người dùng đến URL uỷ quyền bằng cách sử dụng khung ứng dụng web Flask:
return flask.redirect(authorization_url)
Ruby
- Tạo URL để yêu cầu quyền truy cập từ máy chủ OAuth 2.0 của Google:
auth_uri = auth_client.authorization_uri.to_s
- Chuyển hướng người dùng đến
auth_uri
.
Node.js
-
Hãy sử dụng URL được tạo
authorizationUrl
trong phương thức 1generateAuthUrl
để yêu cầu quyền truy cập từ máy chủ OAuth 2.0 của Google. -
Chuyển hướng người dùng đến
authorizationUrl
.res.writeHead(301, { "Location": authorizationUrl });
HTTP/REST
Sample redirect to Google's authorization server
An example URL is shown below, with line breaks and spaces for readability.
https://accounts.google.com/o/oauth2/v2/auth? scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly& access_type=offline& include_granted_scopes=true& response_type=code& state=state_parameter_passthrough_value& redirect_uri=https%3A//oauth2.example.com/code& client_id=client_id
Sau khi bạn tạo URL yêu cầu, hãy chuyển hướng người dùng đến URL yêu cầu.
Máy chủ OAuth 2.0 của Google sẽ xác thực người dùng và có được sự đồng ý của người dùng để ứng dụng của bạn truy cập vào các phạm vi được yêu cầu. Phản hồi được gửi lại ứng dụng của bạn bằng URL chuyển hướng mà bạn đã chỉ định.
Bước 3: Google nhắc người dùng đồng ý
Ở bước này, người dùng quyết định có cấp cho ứng dụng của bạn quyền truy cập đã yêu cầu hay không. Ở giai đoạn này, Google sẽ hiển thị một cửa sổ yêu cầu sự đồng ý để cho biết tên của ứng dụng và các dịch vụ API của Google mà Google đang yêu cầu cấp quyền truy cập bằng thông tin đăng nhập của người dùng cùng với thông tin tóm tắt về phạm vi truy cập cần cấp. Sau đó, người dùng có thể đồng ý cấp quyền truy cập vào một hoặc nhiều phạm vi mà ứng dụng của bạn yêu cầu hoặc từ chối yêu cầu.
Ứng dụng của bạn không cần làm gì ở giai đoạn này vì hệ thống sẽ chờ phản hồi từ máy chủ OAuth 2.0 của Google để cho bạn biết bạn có được cấp quyền truy cập nào hay không. Phản hồi đó sẽ được giải thích trong bước sau.
Lỗi
Các yêu cầu gửi đến điểm cuối uỷ quyền OAuth 2.0 của Google có thể hiển thị thông báo lỗi mà người dùng nhìn thấy thay vì các quy trình xác thực và uỷ quyền dự kiến. Dưới đây là danh sách mã lỗi và các giải pháp đề xuất.
admin_policy_enforced
Tài khoản Google không thể uỷ quyền cho một hoặc nhiều phạm vi yêu cầu theo chính sách của quản trị viên Google Workspace. 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 bên trong 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 cấp quyền truy cập rõ ràng vào mã ứng dụng khách OAuth.
disallowed_useragent
Điểm cuối ủy quyền được hiển thị bên trong tác nhân người dùng được nhúng theo Chính sách OAuth 2.0 của Google.
Android
Nhà phát triển Android có thể gặp thông báo lỗi này khi mở các yêu cầu uỷ quyền trong
android.webkit.WebView
.
Thay vào đó, nhà phát triển nên sử dụng các thư viện Android như Đăng nhập bằng Google cho Android hoặc AppAuth cho Android của WHOIS Foundation.
Nhà phát triển web có thể gặp lỗi này khi một ứng dụng Android mở một đường liên kết web chung trong tác nhân người dùng được nhúng và người dùng sẽ chuyển đến điểm cuối uỷ quyền OAuth 2.0 của Google từ trang web của bạn. Nhà phát triển nên cho phép mở các đường liên kết chung trong trình xử lý đường liên kết mặc định của hệ điều hành, trong đó có cả trình xử lý Đường liên kết trong ứng dụng Android hoặc ứng dụng trình duyệt mặc định. Thư viện Thẻ tuỳ chỉnh Android cũng là một tuỳ chọn được hỗ trợ.
iOS
Nhà phát triển iOS và macOS có thể gặp lỗi này khi mở yêu cầu uỷ quyền trong
WKWebView
.
Thay vào đó, nhà phát triển nên sử dụng các thư viện iOS như Đăng nhập bằng Google cho iOS hoặc AppAuth cho iOS của Orkut Foundation.
Nhà phát triển web có thể gặp lỗi này khi ứng dụng iOS hoặc macOS mở một đường liên kết web chung trong tác nhân người dùng được nhúng và người dùng sẽ chuyển đến điểm cuối uỷ quyền OAuth 2.0 của Google từ trang web của bạn. Nhà phát triển nên cho phép các đường liên kết chung mở trong trình xử lý đường liên kết mặc định của hệ điều hành, trong đó có cả trình xử lý Đường liên kết phổ quát hoặc ứng dụng trình duyệt mặc định. Thư viện SFSafariViewController
cũng là một tuỳ chọn được hỗ trợ.
org_internal
Mã ứng dụng khách 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 Google Cloud cụ thể. Để biết thêm thông tin về tuỳ chọn cấu hình này, hãy xem phần Loại người dùng trong bài viết trợ giúp về Thiết lập màn hình xin phép bằng OAuth.
invalid_client
Mật khẩu ứng dụng khách OAuth không chính xác. Hãy xem lại cấu hình ứng dụng OAuth, trong đó có mã ứng dụng khách và mã bí mật dùng cho yêu cầu này.
invalid_grant
Khi làm mới mã truy cập hoặc sử dụng uỷ quyền gia tăng, mã thông báo có thể đã hết hạn hoặc không hợp lệ. Xác thực lại người dùng và yêu cầu người dùng đồng ý để nhận mã thông báo mới. Nếu bạn vẫn tiếp tục gặp lỗi này, hãy đảm bảo rằng bạn đã định cấu hình đúng cách cho ứng dụng và bạn đang sử dụng đúng mã thông số cũng như thông số trong yêu cầu. Nếu không, tài khoản người dùng có thể đã bị xoá hoặc vô hiệu hoá.
redirect_uri_mismatch
redirect_uri
được chuyển trong yêu cầu uỷ quyền không khớp với URI chuyển hướng được uỷ quyền cho mã ứng dụng khách OAuth. Hãy xem xét các URI chuyển hướng được phép trong Google API Console Credentials page.
Tham số redirect_uri
có thể tham chiếu đến luồng ngoài băng tần (OOB) của OAuth đã không còn được dùng nữa và không còn được hỗ trợ. Hãy tham khảo
hướng dẫn di chuyển để cập nhật
công cụ tích hợp của bạn.
Bước 4: Xử lý phản hồi của máy chủ OAuth 2.0
Máy chủ OAuth 2.0 phản hồi yêu cầu truy cập của ứng dụng bằng cách sử dụng URL được chỉ định trong yêu cầu.
Nếu người dùng chấp thuận yêu cầu truy cập, thì phản hồi sẽ chứa mã uỷ quyền. Nếu người dùng từ chối yêu cầu, thì phản hồi sẽ chứa thông báo lỗi. Mã uỷ quyền hoặc thông báo lỗi được trả về máy chủ web xuất hiện trên chuỗi truy vấn, như minh hoạ dưới đây:
Phản hồi lỗi:
https://oauth2.example.com/auth?error=access_denied
Phản hồi mã uỷ quyền:
https://oauth2.example.com/auth?code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7
Phản hồi của máy chủ OAuth 2.0 mẫu
Bạn có thể kiểm tra quy trình này bằng cách nhấp vào URL mẫu sau đây. URL này yêu cầu quyền truy cập chỉ đọc để xem siêu dữ liệu cho các tệp trong Google Drive của bạn:
https://accounts.google.com/o/oauth2/v2/auth? scope=https%3A//www.googleapis.com/auth/drive.metadata.readonly& access_type=offline& include_granted_scopes=true& response_type=code& state=state_parameter_passthrough_value& redirect_uri=https%3A//oauth2.example.com/code& client_id=client_id
Sau khi hoàn tất quy trình OAuth 2.0, bạn nên được chuyển hướng đến
http://localhost/oauth2callback
, việc này có thể gây ra lỗi
404 NOT FOUND
trừ khi máy cục bộ của bạn phân phát một tệp tại địa chỉ đó. Bước tiếp theo sẽ cung cấp thêm thông tin về những thông tin được trả về trong URI khi người dùng được chuyển hướng trở lại ứng dụng của bạn.
Bước 5: Trao đổi mã uỷ quyền để làm mới và truy cập mã thông báo
Sau khi máy chủ web nhận được mã uỷ quyền, máy chủ có thể đổi mã uỷ quyền cho một mã truy cập.
PHP
Để trao đổi mã uỷ quyền cho mã truy cập, hãy sử dụng phương thức authenticate
:
$client->authenticate($_GET['code']);
Bạn có thể truy xuất mã thông báo truy cập bằng phương thức getAccessToken
:
$access_token = $client->getAccessToken();
Python
Trên trang gọi lại, hãy sử dụng thư viện google-auth
để xác minh phản hồi của máy chủ uỷ quyền. Sau đó, hãy sử dụng phương thức flow.fetch_token
để đổi mã uỷ quyền trong phản hồi đó cho mã truy cập:
state = flask.session['state'] flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( 'client_secret.json', scopes=['https://www.googleapis.com/auth/drive.metadata.readonly'], state=state) flow.redirect_uri = flask.url_for('oauth2callback', _external=True) authorization_response = flask.request.url flow.fetch_token(authorization_response=authorization_response) # Store the credentials in the session. # ACTION ITEM for developers: # Store user's access and refresh tokens in your data store if # incorporating this code into your real app. credentials = flow.credentials flask.session['credentials'] = { 'token': credentials.token, 'refresh_token': credentials.refresh_token, 'token_uri': credentials.token_uri, 'client_id': credentials.client_id, 'client_secret': credentials.client_secret, 'scopes': credentials.scopes}
Ruby
Để trao đổi mã uỷ quyền cho mã truy cập, hãy sử dụng phương thức fetch_access_token!
:
auth_client.code = auth_code auth_client.fetch_access_token!
Node.js
Để trao đổi mã uỷ quyền cho mã truy cập, hãy sử dụng phương thức getToken
:
const url = require('url'); // Receive the callback from Google's OAuth 2.0 server. if (req.url.startsWith('/oauth2callback')) { // Handle the OAuth 2.0 server response let q = url.parse(req.url, true).query; // Get access and refresh tokens (if access_type is offline) let { tokens } = await oauth2Client.getToken(q.code); oauth2Client.setCredentials(tokens); }
HTTP/REST (Hệ thống HTTP/REST)
Để trao đổi mã uỷ quyền cho mã truy cập, hãy gọi điểm cuối https://oauth2.googleapis.com/token
và đặt các thông số sau:
Các trường | |
---|---|
client_id |
Mã ứng dụng khách thu được từ API Console Credentials page. |
client_secret |
Mật khẩu ứng dụng khách lấy từ API Console Credentials page. |
code |
Mã uỷ quyền được trả về từ yêu cầu ban đầu. |
grant_type |
Như được xác định trong thông số kỹ thuật OAuth 2.0, giá trị của trường này phải được đặt thành authorization_code . |
redirect_uri |
Một trong các URI chuyển hướng liệt kê cho dự án của bạn trong API Console
Credentials page của client_id . |
Đoạn mã sau đây cho thấy một yêu cầu mẫu:
POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded code=4/P7q7W91a-oMsCeLvIaQm6bTrgtp7& client_id=your_client_id& client_secret=your_client_secret& redirect_uri=https%3A//oauth2.example.com/code& grant_type=authorization_code
Google phản hồi yêu cầu này bằng cách trả về một đối tượng JSON chứa mã truy cập ngắn hạn và một mã làm mới.
Xin lưu ý rằng mã làm mới chỉ được trả về nếu ứng dụng của bạn đặt thông số access_type
thành offline
trong yêu cầu ban đầu đến
máy chủ uỷ quyền.
Phản hồi chứa các trường sau:
Các trường | |
---|---|
access_token |
Mã thông báo mà ứng dụng của bạn gửi để cho phép một yêu cầu API của Google. |
expires_in |
Thời gian tồn tại của mã truy cập tính bằng giây. |
refresh_token |
Một mã thông báo mà bạn có thể dùng để lấy mã truy cập mới. Mã làm mới sẽ hợp lệ cho đến khi người dùng thu hồi quyền truy cập.
Xin nhắc lại, trường này chỉ xuất hiện trong phản hồi này nếu bạn đặt thông số access_type thành offline trong yêu cầu ban đầu đến máy chủ uỷ quyền của Google.
|
scope |
Phạm vi truy cập mà access_token cấp được biểu thị dưới dạng danh sách các chuỗi được phân tách bằng dấu cách, phân biệt chữ hoa chữ thường. |
token_type |
Loại mã thông báo được trả về. Hiện tại, giá trị của trường này luôn được đặt thành Bearer . |
Đoạn mã sau đây cho thấy một phản hồi mẫu:
{ "access_token": "1/fFAGRNJru1FTz70BzhT3Zg", "expires_in": 3920, "token_type": "Bearer", "scope": "https://www.googleapis.com/auth/drive.metadata.readonly", "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI" }
Lỗi
Khi trao đổi mã uỷ quyền cho mã truy cập, bạn có thể gặp lỗi sau thay vì phản hồi dự kiến. Dưới đây là danh sách các mã lỗi phổ biến và cách giải quyết đề xuất.
invalid_grant
Mã uỷ quyền bạn cung cấp không hợp lệ hoặc có định dạng không chính xác. Yêu cầu mã mới bằng cách bắt đầu lại quy trình OAuth để nhắc người dùng đồng ý lại.
Gọi API của Google
PHP
Sử dụng mã truy cập để gọi API Google bằng cách hoàn tất các bước sau:
- Nếu bạn cần áp dụng mã truy cập cho một đối tượng
Google\Client
mới (ví dụ: nếu bạn đã lưu trữ mã truy cập trong một phiên truy cập của người dùng), hãy sử dụng phương thứcsetAccessToken
:$client->setAccessToken($access_token);
- Xây dựng một đối tượng dịch vụ cho API mà bạn muốn gọi. Bạn tạo đối tượng dịch vụ bằng cách cung cấp một đối tượng
Google\Client
được ủy quyền cho hàm khởi tạo cho API mà bạn muốn gọi. Ví dụ: để gọi API Drive:$drive = new Google\Service\Drive($client);
- Tạo 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 tệp trong Google Drive của người dùng được xác thực, hãy làm như sau:
$files = $drive->files->listFiles(array())->getItems();
Python
Sau khi có được mã truy cập, ứng dụng của bạn có thể sử dụng mã đó để uỷ quyền cho các yêu cầu API thay mặt cho một tài khoản người dùng hoặc tài khoản dịch vụ nhất định. Sử dụng thông tin cấp phép của từng người dùng để tạo đối tượng dịch vụ cho API mà bạn muốn gọi, sau đó sử dụng đối tượng đó để tạo các yêu cầu API được uỷ quyền.
- Xây dựng một đố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 phương thức
build
của thư việngoogleapiclient.discovery
bằng tên và phiên bản của API cũng như thông tin xác thực của người dùng: Ví dụ: để gọi phiên bản 2 của API Drive:from googleapiclient.discovery import build drive = build('drive', 'v2', credentials=credentials)
- Tạo 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 tệp trong Google Drive của người dùng được xác thực, hãy làm như sau:
files = drive.files().list().execute()
Ruby
Sử dụng đối tượng auth_client
để gọi các API của Google bằng cách hoàn thành các bước sau:
- Xây dựng một đối tượng dịch vụ cho API mà bạn muốn gọi.
Ví dụ: để gọi phiên bản 2 của API Drive:
drive = Google::Apis::DriveV2::DriveService.new
- Đặt thông tin xác thực trên dịch vụ:
drive.authorization = auth_client
- Tạo 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 tệp trong Google Drive của người dùng đã xác thực:
files = drive.list_files
Ngoài ra, bạn có thể uỷ quyền trên cơ sở từng phương thức bằng cách cung cấp tham số options
cho một phương thức:
files = drive.list_files(options: { authorization: auth_client })
Node.js
Sau khi nhận được mã truy cập và đặt mã đó thành đối tượng OAuth2
, hãy sử dụng đối tượng đó để gọi các API của Google. Ứng dụng của bạn có thể sử dụng mã thông báo đó để uỷ quyền cho các yêu cầu API thay mặt cho một tài khoản người dùng hoặc tài khoản dịch vụ nhất định. Xây dựng một đối tượng dịch vụ cho API mà bạn muốn gọi.
const { google } = require('googleapis'); // Example of using Google Drive API to list filenames in user's Drive. const drive = google.drive('v3'); drive.files.list({ auth: oauth2Client, pageSize: 10, fields: 'nextPageToken, files(id, name)', }, (err1, res1) => { if (err1) return console.log('The API returned an error: ' + err1); const files = res1.data.files; if (files.length) { console.log('Files:'); files.map((file) => { console.log(`${file.name} (${file.id})`); }); } else { console.log('No files found.'); } });
HTTP/REST (Hệ thống 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ã thông báo này để gọi API Google thay mặt cho một tài khoản người dùng nhất định nếu API đó đã cấp(các) phạm vi quyền truy cập mà ứng dụng cần. Để 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 thêm giá trị tham số truy vấn access_token
hoặc Authorization
tiêu đề HTTP Bearer
. Khi có thể, bạn nên chọn tiêu đề HTTP vì các chuỗi cụm từ tìm kiếm có xu hướng xuất hiện trong nhật ký máy chủ. Trong hầu hết trường hợp, bạn có thể sử dụng một 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 Drive Files).
Bạn có thể dùng thử tất cả API của Google và xem phạm vi của các API đó tại OAuth 2.0 Playground.
Ví dụ về HTTP GET
Lệnh gọi đến điểm cuối
drive.files
(API Drive Files) sử dụ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 chính mình:
GET /drive/v2/files HTTP/1.1 Host: www.googleapis.com Authorization: Bearer access_token
Sau đâ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
. Sau đây là một 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, tùy chọn tham số chuỗi truy vấn:
curl https://www.googleapis.com/drive/v2/files?access_token=access_token
Ví dụ đầy đủ
Ví dụ sau đây in một danh sách các tệp có định dạng JSON trên Google Drive của người dùng sau khi người dùng xác thực và đồng ý cho ứng dụng truy cập vào siêu dữ liệu trên Drive của người dùng.
PHP
Để chạy ví dụ này, hãy làm như sau:
- Trong API Console, hãy thêm URL của máy cục bộ vào danh sách các URL chuyển hướng. Ví dụ: thêm
http://localhost:8080
. - Tạo thư mục mới và thay đổi sang thư mục đó. Ví dụ:
mkdir ~/php-oauth2-example cd ~/php-oauth2-example
- Cài đặt Thư viện ứng dụng API của Google cho PHP bằng Composer:
composer require google/apiclient:^2.10
- Tạo các tệp
index.php
vàoauth2callback.php
bằng nội dung dưới đây. - Chạy ví dụ bằng máy chủ web được định cấu hình để phân phát PHP. Nếu sử dụng PHP 5.6 trở lên, bạn
có thể sử dụng máy chủ web thử nghiệm tích hợp của PHP:
php -S localhost:8080 ~/php-oauth2-example
index.php
<?php require_once __DIR__.'/vendor/autoload.php'; session_start(); $client = new Google\Client(); $client->setAuthConfig('client_secrets.json'); $client->addScope(Google\Service\Drive::DRIVE_METADATA_READONLY); if (isset($_SESSION['access_token']) && $_SESSION['access_token']) { $client->setAccessToken($_SESSION['access_token']); $drive = new Google\Service\Drive($client); $files = $drive->files->listFiles(array())->getItems(); echo json_encode($files); } else { $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php'; header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL)); }
OAuth2callback.php
<?php require_once __DIR__.'/vendor/autoload.php'; session_start(); $client = new Google\Client(); $client->setAuthConfigFile('client_secrets.json'); $client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php'); $client->addScope(Google\Service\Drive::DRIVE_METADATA_READONLY); if (! isset($_GET['code'])) { $auth_url = $client->createAuthUrl(); header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL)); } else { $client->authenticate($_GET['code']); $_SESSION['access_token'] = $client->getAccessToken(); $redirect_uri = 'http://' . $_SERVER['HTTP_HOST'] . '/'; header('Location: ' . filter_var($redirect_uri, FILTER_SANITIZE_URL)); }
Python
Ví dụ này sử dụng khung Flask. Công cụ này chạy một ứng dụng web tại http://localhost:8080
cho phép bạn kiểm thử quy trình OAuth 2.0. Nếu truy cập vào URL đó, bạn sẽ thấy 4 đường liên kết:
- Test a API request (Kiểm tra yêu cầu API): Đường liên kết này trỏ đến một trang cố gắng thực thi yêu cầu API mẫu. Nếu cần, sẽ bắt đầu quy trình uỷ quyền. Nếu thành công, trang sẽ hiển thị phản hồi của API.
- Kiểm tra trực tiếp quy trình xác thực: Đường liên kết này trỏ đến một trang cố gắng chuyển người dùng đến quy trình uỷ quyền. Ứng dụng này yêu cầu quyền để gửi các yêu cầu API được uỷ quyền thay mặt cho người dùng.
- Thu hồi thông tin xác thực hiện tại: Đường liên kết này trỏ đến một trang thu hồi các quyền mà người dùng đã cấp cho ứng dụng.
- Xoá thông tin xác thực về phiên hoạt động: Bình luận: Đường liên kết này sẽ xóa thông tin xác thực ủy quyền được lưu trữ trong phiên hoạt động Bình luận. Điều này cho phép bạn xem điều gì sẽ xảy ra nếu người dùng đã cấp quyền cho ứng dụng của bạn cố gắng thực thi yêu cầu API trong một phiên mới. Việc này cũng cho phép bạn xem phản hồi API mà ứng dụng của bạn sẽ nhận được nếu người dùng đã thu hồi quyền đã cấp cho ứng dụng của bạn, và ứng dụng vẫn cố gắng cho phép một yêu cầu bằng mã truy cập đã thu hồi.
# -*- coding: utf-8 -*- import os import flask import requests import google.oauth2.credentials import google_auth_oauthlib.flow import googleapiclient.discovery # This variable specifies the name of a file that contains the OAuth 2.0 # information for this application, including its client_id and client_secret. CLIENT_SECRETS_FILE = "client_secret.json" # This OAuth 2.0 access scope allows for full read/write access to the # authenticated user's account and requires requests to use an SSL connection. SCOPES = ['https://www.googleapis.com/auth/drive.metadata.readonly'] API_SERVICE_NAME = 'drive' API_VERSION = 'v2' app = flask.Flask(__name__) # Note: A secret key is included in the sample so that it works. # If you use this code in your application, replace this with a truly secret # key. See https://flask.palletsprojects.com/quickstart/#sessions. app.secret_key = 'REPLACE ME - this value is here as a placeholder.' @app.route('/') def index(): return print_index_table() @app.route('/test') def test_api_request(): if 'credentials' not in flask.session: return flask.redirect('authorize') # Load credentials from the session. credentials = google.oauth2.credentials.Credentials( **flask.session['credentials']) drive = googleapiclient.discovery.build( API_SERVICE_NAME, API_VERSION, credentials=credentials) files = drive.files().list().execute() # Save credentials back to session in case access token was refreshed. # ACTION ITEM: In a production app, you likely want to save these # credentials in a persistent database instead. flask.session['credentials'] = credentials_to_dict(credentials) return flask.jsonify(**files) @app.route('/authorize') def authorize(): # Create flow instance to manage the OAuth 2.0 Authorization Grant Flow steps. flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( CLIENT_SECRETS_FILE, scopes=SCOPES) # The URI created here must exactly match one of the authorized redirect URIs # for the OAuth 2.0 client, which you configured in the API Console. If this # value doesn't match an authorized URI, you will get a 'redirect_uri_mismatch' # error. flow.redirect_uri = flask.url_for('oauth2callback', _external=True) authorization_url, state = flow.authorization_url( # Enable offline access so that you can refresh an access token without # re-prompting the user for permission. Recommended for web server apps. access_type='offline', # Enable incremental authorization. Recommended as a best practice. include_granted_scopes='true') # Store the state so the callback can verify the auth server response. flask.session['state'] = state return flask.redirect(authorization_url) @app.route('/oauth2callback') def oauth2callback(): # Specify the state when creating the flow in the callback so that it can # verified in the authorization server response. state = flask.session['state'] flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( CLIENT_SECRETS_FILE, scopes=SCOPES, state=state) flow.redirect_uri = flask.url_for('oauth2callback', _external=True) # Use the authorization server's response to fetch the OAuth 2.0 tokens. authorization_response = flask.request.url flow.fetch_token(authorization_response=authorization_response) # Store credentials in the session. # ACTION ITEM: In a production app, you likely want to save these # credentials in a persistent database instead. credentials = flow.credentials flask.session['credentials'] = credentials_to_dict(credentials) return flask.redirect(flask.url_for('test_api_request')) @app.route('/revoke') def revoke(): if 'credentials' not in flask.session: return ('You need to <a href="/authorize">authorize</a> before ' + 'testing the code to revoke credentials.') credentials = google.oauth2.credentials.Credentials( **flask.session['credentials']) revoke = requests.post('https://oauth2.googleapis.com/revoke', params={'token': credentials.token}, headers = {'content-type': 'application/x-www-form-urlencoded'}) status_code = getattr(revoke, 'status_code') if status_code == 200: return('Credentials successfully revoked.' + print_index_table()) else: return('An error occurred.' + print_index_table()) @app.route('/clear') def clear_credentials(): if 'credentials' in flask.session: del flask.session['credentials'] return ('Credentials have been cleared.<br><br>' + print_index_table()) def credentials_to_dict(credentials): return {'token': credentials.token, 'refresh_token': credentials.refresh_token, 'token_uri': credentials.token_uri, 'client_id': credentials.client_id, 'client_secret': credentials.client_secret, 'scopes': credentials.scopes} def print_index_table(): return ('<table>' + '<tr><td><a href="/test">Test an API request</a></td>' + '<td>Submit an API request and see a formatted JSON response. ' + ' Go through the authorization flow if there are no stored ' + ' credentials for the user.</td></tr>' + '<tr><td><a href="/authorize">Test the auth flow directly</a></td>' + '<td>Go directly to the authorization flow. If there are stored ' + ' credentials, you still might not be prompted to reauthorize ' + ' the application.</td></tr>' + '<tr><td><a href="/revoke">Revoke current credentials</a></td>' + '<td>Revoke the access token associated with the current user ' + ' session. After revoking credentials, if you go to the test ' + ' page, you should see an <code>invalid_grant</code> error.' + '</td></tr>' + '<tr><td><a href="/clear">Clear Flask session credentials</a></td>' + '<td>Clear the access token currently stored in the user session. ' + ' After clearing the token, if you <a href="/test">test the ' + ' API request</a> again, you should go back to the auth flow.' + '</td></tr></table>') if __name__ == '__main__': # When running locally, disable OAuthlib's HTTPs verification. # ACTION ITEM for developers: # When running in production *do not* leave this option enabled. os.environ['OAUTHLIB_INSECURE_TRANSPORT'] = '1' # Specify a hostname and port that are set as a valid redirect URI # for your API project in the Google API Console. app.run('localhost', 8080, debug=True)
Ruby
Ví dụ này sử dụng khung Sinatra.
require 'google/apis/drive_v2' require 'google/api_client/client_secrets' require 'json' require 'sinatra' enable :sessions set :session_secret, 'setme' get '/' do unless session.has_key?(:credentials) redirect to('/oauth2callback') end client_opts = JSON.parse(session[:credentials]) auth_client = Signet::OAuth2::Client.new(client_opts) drive = Google::Apis::DriveV2::DriveService.new files = drive.list_files(options: { authorization: auth_client }) "<pre>#{JSON.pretty_generate(files.to_h)}</pre>" end get '/oauth2callback' do client_secrets = Google::APIClient::ClientSecrets.load auth_client = client_secrets.to_authorization auth_client.update!( :scope => 'https://www.googleapis.com/auth/drive.metadata.readonly', :redirect_uri => url('/oauth2callback')) if request['code'] == nil auth_uri = auth_client.authorization_uri.to_s redirect to(auth_uri) else auth_client.code = request['code'] auth_client.fetch_access_token! auth_client.client_secret = nil session[:credentials] = auth_client.to_json redirect to('/') end end
Node.js
Để chạy ví dụ này, hãy làm như sau:
-
Trong API Console, hãy thêm URL của máy cục bộ vào danh sách các URL chuyển hướng. Ví dụ: thêm
http://localhost
. - Đảm bảo bạn đã cài đặt LTS (hỗ trợ dài hạn), LTS (đang hoạt động) hoặc phát hành phiên bản Node.js hiện tại.
-
Tạo thư mục mới và thay đổi sang thư mục đó. Ví dụ:
mkdir ~/nodejs-oauth2-example cd ~/nodejs-oauth2-example
-
Install the
Google API Client
Library
for Node.js using npm:
npm install googleapis
-
Tạo các tệp
main.js
bằng nội dung bên dưới. -
Chạy ví dụ:
node .\main.js
main.js
const http = require('http'); const https = require('https'); const url = require('url'); const { google } = require('googleapis'); /** * To use OAuth2 authentication, we need access to a CLIENT_ID, CLIENT_SECRET, AND REDIRECT_URI. * To get these credentials for your application, visit * https://console.cloud.google.com/apis/credentials. */ const oauth2Client = new google.auth.OAuth2( YOUR_CLIENT_ID, YOUR_CLIENT_SECRET, YOUR_REDIRECT_URL ); // Access scopes for read-only Drive activity. const scopes = [ 'https://www.googleapis.com/auth/drive.metadata.readonly' ]; // Generate a url that asks permissions for the Drive activity scope const authorizationUrl = oauth2Client.generateAuthUrl({ // 'online' (default) or 'offline' (gets refresh_token) access_type: 'offline', /** Pass in the scopes array defined above. * Alternatively, if only one scope is needed, you can pass a scope URL as a string */ scope: scopes, // Enable incremental authorization. Recommended as a best practice. include_granted_scopes: true }); /* Global variable that stores user credential in this code example. * ACTION ITEM for developers: * Store user's refresh token in your data store if * incorporating this code into your real app. * For more information on handling refresh tokens, * see https://github.com/googleapis/google-api-nodejs-client#handling-refresh-tokens */ let userCredential = null; async function main() { const server = http.createServer(async function (req, res) { // Example on redirecting user to Google's OAuth 2.0 server. if (req.url == '/') { res.writeHead(301, { "Location": authorizationUrl }); } // Receive the callback from Google's OAuth 2.0 server. if (req.url.startsWith('/oauth2callback')) { // Handle the OAuth 2.0 server response let q = url.parse(req.url, true).query; if (q.error) { // An error response e.g. error=access_denied console.log('Error:' + q.error); } else { // Get access and refresh tokens (if access_type is offline) let { tokens } = await oauth2Client.getToken(q.code); oauth2Client.setCredentials(tokens); /** Save credential to the global variable in case access token was refreshed. * ACTION ITEM: In a production app, you likely want to save the refresh token * in a secure persistent database instead. */ userCredential = tokens; // Example of using Google Drive API to list filenames in user's Drive. const drive = google.drive('v3'); drive.files.list({ auth: oauth2Client, pageSize: 10, fields: 'nextPageToken, files(id, name)', }, (err1, res1) => { if (err1) return console.log('The API returned an error: ' + err1); const files = res1.data.files; if (files.length) { console.log('Files:'); files.map((file) => { console.log(`${file.name} (${file.id})`); }); } else { console.log('No files found.'); } }); } } // Example on revoking a token if (req.url == '/revoke') { // Build the string for the POST request let postData = "token=" + userCredential.access_token; // Options for POST request to Google's OAuth 2.0 server to revoke a token let postOptions = { host: 'oauth2.googleapis.com', port: '443', path: '/revoke', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': Buffer.byteLength(postData) } }; // Set up the request const postReq = https.request(postOptions, function (res) { res.setEncoding('utf8'); res.on('data', d => { console.log('Response: ' + d); }); }); postReq.on('error', error => { console.log(error) }); // Post the request with data postReq.write(postData); postReq.end(); } res.end(); }).listen(80); } main().catch(console.error);
HTTP/REST (Hệ thống HTTP/REST)
Ví dụ về Python này sử dụng khung Flask và thư viện Yêu cầu để minh hoạ luồng web OAuth 2.0. Bạn nên sử dụng Thư viện ứng dụng Python cho API của Google cho quy trình này. (Ví dụ trong thẻ Python có sử dụng thư viện ứng dụng.)
import json import flask import requests app = flask.Flask(__name__) CLIENT_ID = '123456789.apps.googleusercontent.com' CLIENT_SECRET = 'abc123' # Read from a file or environmental variable in a real app SCOPE = 'https://www.googleapis.com/auth/drive.metadata.readonly' REDIRECT_URI = 'http://example.com/oauth2callback' @app.route('/') def index(): if 'credentials' not in flask.session: return flask.redirect(flask.url_for('oauth2callback')) credentials = json.loads(flask.session['credentials']) if credentials['expires_in'] <= 0: return flask.redirect(flask.url_for('oauth2callback')) else: headers = {'Authorization': 'Bearer {}'.format(credentials['access_token'])} req_uri = 'https://www.googleapis.com/drive/v2/files' r = requests.get(req_uri, headers=headers) return r.text @app.route('/oauth2callback') def oauth2callback(): if 'code' not in flask.request.args: auth_uri = ('https://accounts.google.com/o/oauth2/v2/auth?response_type=code' '&client_id={}&redirect_uri={}&scope={}').format(CLIENT_ID, REDIRECT_URI, SCOPE) return flask.redirect(auth_uri) else: auth_code = flask.request.args.get('code') data = {'code': auth_code, 'client_id': CLIENT_ID, 'client_secret': CLIENT_SECRET, 'redirect_uri': REDIRECT_URI, 'grant_type': 'authorization_code'} r = requests.post('https://oauth2.googleapis.com/token', data=data) flask.session['credentials'] = r.text return flask.redirect(flask.url_for('index')) if __name__ == '__main__': import uuid app.secret_key = str(uuid.uuid4()) app.debug = False app.run()
Các quy tắc xác thực URI chuyển hướng
Google áp dụng các quy tắc xác thực sau để chuyển hướng URI nhằm giúp nhà phát triển bảo mật ứng dụng của họ. URI chuyển hướng của bạn phải tuân thủ các quy tắc này. Vui lòng xem RFC 3986 phần 3 để biết định nghĩa về miền, máy chủ, đường dẫn, truy vấn, lược đồ và thông tin người dùng như bên dưới.
Các quy tắc xác thực | |
---|---|
Lược đồ |
URI chuyển hướng phải sử dụng lược đồ HTTPS, không được sử dụng HTTP thuần tuý. URI máy chủ cục bộ (bao gồm cả URI địa chỉ IP localhost) được miễn khỏi quy tắc này. |
Máy chủ |
Máy chủ không thể là địa chỉ IP thô. Địa chỉ IP máy chủ cục bộ được miễn trừ quy tắc này. |
Miền |
“googleusercontent.com” .goo.gl ), trừ phi ứng dụng sở hữu miền này. Hơn nữa, nếu một ứng dụng sở hữu miền rút gọn chọn chuyển hướng đến miền đó, thì URI chuyển hướng đó phải chứa “/google-callback/” trong đường dẫn hoặc kết thúc bằng “/google-callback” . |
Thông tin người dùng |
URI chuyển hướng không được chứa thành phần phụ userinfo. |
Đường dẫn |
URI chuyển hướng không được chứa một đường dẫn truyền tải (còn gọi là theo dõi ngược lại thư mục), được biểu thị bằng |
Cụm từ tìm kiếm |
URI chuyển hướng không được chứa lệnh chuyển hướng mở. |
Mảnh |
URI chuyển hướng không được chứa thành phần mảnh. |
Ký tự |
URI chuyển hướng không được chứa một số ký tự cụ thể, bao gồm:
|
Uỷ quyền gia tăng
Trong giao thức OAuth 2.0, ứng dụng yêu cầu cấp quyền truy cập vào các tài nguyên được xác định theo phạm vi. Đây là phương pháp hay nhất khi dùng trải nghiệm người dùng để yêu cầu cấp quyền cho các tài nguyên tại thời điểm bạn cần. Để áp dụng cách đó, máy chủ uỷ quyền của Google hỗ trợ uỷ quyền dần. Tính năng này cho phép bạn yêu cầu phạm vi khi cần và nếu người dùng cấp quyền cho phạm vi mới, sẽ trả về mã uỷ quyền có thể được trao đổi để lấy mã thông báo chứa tất cả phạm vi mà người dùng đã cấp dự án.
Ví dụ: một ứng dụng cho phép mọi người lấy mẫu bản nhạc và tạo danh sách kết hợp có thể cần rất ít tài nguyên tại thời điểm đăng nhập, có thể không có gì khác ngoài tên của người đăng nhập. Tuy nhiên, bạn cần có quyền truy cập vào Google Drive để lưu danh sách kết hợp hoàn chỉnh. Hầu hết mọi người đều nhận thấy điều này là tự nhiên nếu họ chỉ được yêu cầu cấp quyền truy cập vào Google Drive tại thời điểm ứng dụng thực sự cần.
Trong trường hợp này, tại thời điểm đăng nhập, ứng dụng có thể yêu cầu phạm vi openid
và profile
để thực hiện quá trình đăng nhập cơ bản, sau đó yêu cầu phạm vi https://www.googleapis.com/auth/drive.file
tại thời điểm yêu cầu đầu tiên lưu kết hợp.
Để triển khai lệnh uỷ quyền tăng dần, bạn đã hoàn tất quy trình thông thường để yêu cầu mã truy cập, nhưng hãy đảm bảo rằng yêu cầu uỷ quyền có bao gồm các phạm vi đã cấp trước đó. Phương pháp này cho phép ứng dụng của bạn không phải quản lý nhiều mã truy cập.
Các quy tắc sau áp dụng cho mã truy cập thu được từ việc ủy quyền gia tăng:
- Bạn có thể sử dụng mã thông báo để truy cập vào tài nguyên tương ứng với bất kỳ phạm vi nào được cuộn vào quyền mới, kết hợp.
- Khi bạn sử dụng mã làm mới cho mã uỷ quyền kết hợp để lấy mã truy cập, mã truy cập này đại diện cho mã uỷ quyền kết hợp và có thể dùng cho mọi giá trị
scope
có trong phản hồi. - Quy trình uỷ quyền kết hợp bao gồm mọi phạm vi mà người dùng đã cấp cho dự án API ngay cả khi các yêu cầu trợ cấp được yêu cầu từ nhiều ứng dụng. Ví dụ: nếu người dùng cấp quyền truy cập vào một phạm vi bằng ứng dụng khách dành cho máy tính của ứng dụng, sau đó cấp một phạm vi khác cho cùng một ứng dụng thông qua ứng dụng di động, thì việc uỷ quyền kết hợp sẽ bao gồm cả hai phạm vi.
- Nếu bạn thu hồi một mã xác minh đại diện cho một khoản uỷ quyền kết hợp, thì quyền truy cập vào tất cả các phạm vi uỷ quyền đó thay mặt cho người dùng được liên kết sẽ bị thu hồi đồng thời.
Các mã mẫu theo ngôn ngữ cụ thể trong Bước 1: Đặt các thông số uỷ quyền và URL chuyển hướng HTTP/REST mẫu trong Bước 2: Chuyển hướng đến máy chủ OAuth 2.0 của Google đều sử dụng phương thức uỷ quyền gia tăng. Mã mẫu bên dưới cũng cho thấy mã mà bạn cần thêm để sử dụng tính năng uỷ quyền gia tăng.
PHP
$client->setIncludeGrantedScopes(true);
Python
Trong Python, hãy đặt đối số từ khoá include_granted_scopes
thành true
để đảm bảo rằng một yêu cầu uỷ quyền có bao gồm các phạm vi đã cấp trước đó. Rất có thể include_granted_scopes
sẽ không phải là đối số từ khóa duy nhất mà bạn đặt, như minh hoạ trong ví dụ dưới đây.
authorization_url, state = flow.authorization_url( # Enable offline access so that you can refresh an access token without # re-prompting the user for permission. Recommended for web server apps. access_type='offline', # Enable incremental authorization. Recommended as a best practice. include_granted_scopes='true')
Ruby
auth_client.update!( :additional_parameters => {"include_granted_scopes" => "true"} )
Node.js
const authorizationUrl = oauth2Client.generateAuthUrl({ // 'online' (default) or 'offline' (gets refresh_token) access_type: 'offline', /** Pass in the scopes array defined above. * Alternatively, if only one scope is needed, you can pass a scope URL as a string */ scope: scopes, // Enable incremental authorization. Recommended as a best practice. include_granted_scopes: true });
HTTP/REST (Hệ thống HTTP/REST)
GET https://accounts.google.com/o/oauth2/v2/auth? client_id=your_client_id& response_type=code& state=state_parameter_passthrough_value& scope=https%3A//www.googleapis.com/auth/drive.file& redirect_uri=https%3A//oauth2.example.com/code& prompt=consent& include_granted_scopes=true
Làm mới mã truy cập (truy cập ngoại tuyến)
Mã thông báo truy cập sẽ hết hạn và định kỳ trở thành thông tin xác thực không hợp lệ cho yêu cầu API có liên quan. Bạn có thể làm mới mã truy cập mà không cần nhắc người dùng cấp quyền (bao gồm cả khi người dùng không có mặt) nếu bạn đã yêu cầu quyền truy cập ngoại tuyến vào các phạm vi liên kết với mã thông báo đó.
- Nếu bạn sử dụng một Thư viện ứng dụng API của Google, thì đối tượng ứng dụng khách sẽ làm mới mã thông báo truy cập này khi cần, miễn là bạn định cấu hình đối tượng đó để truy cập khi không có mạng.
- Nếu không sử dụng thư viện ứng dụng, bạn cần đặt tham số truy vấn HTTP
access_type
thànhoffline
khi chuyển hướng người dùng đến máy chủ OAuth 2.0 của Google. Trong trường hợp đó, máy chủ uỷ quyền của Google sẽ trả về một mã làm mới khi bạn trao đổi mã uỷ quyền để lấy mã truy cập. Sau đó, nếu mã truy cập hết hạn (hoặc bất cứ lúc nào khác), bạn có thể dùng mã làm mới để lấy mã truy cập mới.
Yêu cầu truy cập ngoại tuyến là yêu cầu đối với những ứng dụng cần truy cập API Google khi người dùng không có mặt. Ví dụ: một ứng dụng thực hiện dịch vụ sao lưu hoặc thực thi các hành động vào thời điểm định sẵn cần phải làm mới mã truy cập của ứng dụng khi không có người dùng. Kiểu truy cập mặc định được gọi là online
.
Tất cả ứng dụng web phía máy chủ, ứng dụng đã cài đặt và thiết bị đều nhận được mã làm mới trong quá trình uỷ quyền. Mã làm mới thường không được dùng trong các ứng dụng web phía máy khách (JavaScript).
PHP
Nếu ứng dụng của bạn cần quyền truy cập ngoại tuyến vào một API của Google, hãy đặt loại quyền truy cập của ứng dụng API thành
offline
:
$client->setAccessType("offline");
Sau khi người dùng cấp quyền truy cập ngoại tuyến vào các phạm vi yêu cầu, bạn có thể tiếp tục sử dụng ứng dụng API để thay mặt người dùng truy cập các API của Google khi người dùng không có kết nối mạng. Đối tượng ứng dụng khách sẽ làm mới mã truy cập khi cần.
Python
Trong Python, hãy đặt đối số từ khoá access_type
thành offline
để đảm bảo rằng bạn có thể làm mới mã truy cập mà không phải nhắc lại người dùng để cấp quyền. Rất có thể access_type
sẽ không phải là đối số từ khóa duy nhất mà bạn đặt, như minh họa trong ví dụ bên dưới.
authorization_url, state = flow.authorization_url( # Enable offline access so that you can refresh an access token without # re-prompting the user for permission. Recommended for web server apps. access_type='offline', # Enable incremental authorization. Recommended as a best practice. include_granted_scopes='true')
Sau khi người dùng cấp quyền truy cập ngoại tuyến vào các phạm vi yêu cầu, bạn có thể tiếp tục sử dụng ứng dụng API để thay mặt người dùng truy cập các API của Google khi người dùng không có kết nối mạng. Đối tượng ứng dụng khách sẽ làm mới mã truy cập khi cần.
Ruby
Nếu ứng dụng của bạn cần quyền truy cập ngoại tuyến vào một API của Google, hãy đặt loại quyền truy cập của ứng dụng API thành
offline
:
auth_client.update!( :additional_parameters => {"access_type" => "offline"} )
Sau khi người dùng cấp quyền truy cập ngoại tuyến vào các phạm vi yêu cầu, bạn có thể tiếp tục sử dụng ứng dụng API để thay mặt người dùng truy cập các API của Google khi người dùng không có kết nối mạng. Đối tượng ứng dụng khách sẽ làm mới mã truy cập khi cần.
Node.js
Nếu ứng dụng của bạn cần quyền truy cập ngoại tuyến vào một API của Google, hãy đặt loại quyền truy cập của ứng dụng API thành
offline
:
const authorizationUrl = oauth2Client.generateAuthUrl({ // 'online' (default) or 'offline' (gets refresh_token) access_type: 'offline', /** Pass in the scopes array defined above. * Alternatively, if only one scope is needed, you can pass a scope URL as a string */ scope: scopes, // Enable incremental authorization. Recommended as a best practice. include_granted_scopes: true });
Sau khi người dùng cấp quyền truy cập ngoại tuyến vào các phạm vi yêu cầu, bạn có thể tiếp tục sử dụng ứng dụng API để thay mặt người dùng truy cập các API của Google khi người dùng không có kết nối mạng. Đối tượng ứng dụng khách sẽ làm mới mã truy cập khi cần.
Mã thông báo truy cập hết hạn. Thư viện này sẽ tự động sử dụng mã làm mới để lấy mã truy cập mới nếu sắp hết hạn. Một cách dễ dàng để đảm bảo bạn luôn lưu trữ mã thông báo gần đây nhất là sử dụng sự kiện mã thông báo:
oauth2Client.on('tokens', (tokens) => { if (tokens.refresh_token) { // store the refresh_token in your secure persistent database console.log(tokens.refresh_token); } console.log(tokens.access_token); });
Sự kiện mã thông báo này chỉ xảy ra trong lần uỷ quyền đầu tiên và bạn cần phải đặt access_type
thành offline
khi gọi phương thức generateAuthUrl
để nhận mã làm mới. Nếu bạn đã cấp cho ứng dụng quyền yêu cầu mà không cần đặt các điều kiện ràng buộc phù hợp để nhận mã làm mới, thì bạn sẽ cần uỷ quyền lại cho ứng dụng để nhận mã làm mới.
Để thiết lập refresh_token
sau này, bạn có thể sử dụng phương thức setCredentials
:
oauth2Client.setCredentials({ refresh_token: `STORED_REFRESH_TOKEN` });
Sau khi ứng dụng có mã làm mới, mã truy cập sẽ tự động được lấy và làm mới trong lệnh gọi API tiếp theo.
HTTP/REST (Hệ thống HTTP/REST)
Để làm mới mã truy cập, ứng dụng của bạn sẽ gửi yêu cầu HTTPS POST
đến máy chủ uỷ quyền của Google (https://oauth2.googleapis.com/token
) có chứa các tham số sau:
Các trường | |
---|---|
client_id |
Mã ứng dụng khách thu được từ API Console. |
client_secret |
Mật khẩu ứng dụng khách lấy từ API Console. |
grant_type |
Như
đã xác định trong
thông số kỹ thuật OAuth 2.0,
giá trị của trường này phải được đặt thành refresh_token . |
refresh_token |
Mã làm mới được trả về từ hoạt động trao đổi mã uỷ quyền. |
Đoạn mã sau đây cho thấy một yêu cầu mẫu:
POST /token HTTP/1.1 Host: oauth2.googleapis.com Content-Type: application/x-www-form-urlencoded client_id=your_client_id& client_secret=your_client_secret& refresh_token=refresh_token& grant_type=refresh_token
Miễn là người dùng chưa thu hồi quyền truy cập đã cấp cho ứng dụng, máy chủ mã thông báo sẽ trả về đối tượng JSON chứa mã truy cập mới. Đoạn mã sau đây cho thấy một phản hồi mẫu:
{ "access_token": "1/fFAGRNJru1FTz70BzhT3Zg", "expires_in": 3920, "scope": "https://www.googleapis.com/auth/drive.metadata.readonly", "token_type": "Bearer" }
Xin lưu ý rằng có giới hạn về số lượng mã thông báo làm mới sẽ được phát hành; một giới hạn cho mỗi tổ hợp khách hàng/người dùng và một giới hạn cho mỗi người dùng trên tất cả ứng dụng. Bạn nên lưu mã làm mới trong bộ nhớ dài hạn rồi tiếp tục sử dụng cho đến khi chúng vẫn hợp lệ. Nếu ứng dụng của bạn yêu cầu quá nhiều mã làm mới, thì ứng dụng có thể gặp phải các giới hạn này. Trong trường hợp đó, mã làm mới cũ sẽ ngừng hoạt động.
Thu hồi mã thông báo
Trong một số trường hợp, người dùng có thể muốn thu hồi quyền truy cập đã cấp cho một ứng dụng. Người dùng có thể thu hồi quyền truy cập bằng cách truy cập vào phần Cài đặt tài khoản. Hãy xem tài liệu hỗ trợ Xoá trang web hoặc ứng dụng của các trang web và ứng dụng bên thứ ba có quyền truy cập vào tài khoản của bạn để biết thêm thông tin.
Ứng dụng cũng có thể thu hồi quyền truy cập đã cấp cho ứng dụng theo phương thức lập trình. Thu hồi có lập trình có ý nghĩa quan trọng trong trường hợp người dùng hủy đăng ký, xóa một ứng dụng hoặc tài nguyên API mà ứng dụng yêu cầu đã thay đổi đáng kể. Nói cách khác, một phần trong quy trình xóa có thể bao gồm một yêu cầu API để đảm bảo các quyền đã cấp cho ứng dụng trước đó đã bị xóa.
PHP
Để thu hồi mã thông báo theo phương thức lập trình, hãy gọi revokeToken()
:
$client->revokeToken();
Python
Để thu hồi mã thông báo theo phương thức lập trình, hãy yêu cầu https://oauth2.googleapis.com/revoke
bao gồm mã thông báo dưới dạng thông số và đặt tiêu đề Content-Type
:
requests.post('https://oauth2.googleapis.com/revoke', params={'token': credentials.token}, headers = {'content-type': 'application/x-www-form-urlencoded'})
Ruby
Để thu hồi mã thông báo theo phương thức lập trình, hãy gửi yêu cầu HTTP đến điểm cuối oauth2.revoke
:
uri = URI('https://oauth2.googleapis.com/revoke') response = Net::HTTP.post_form(uri, 'token' => auth_client.access_token)
Mã này có thể là mã truy cập hoặc mã làm mới. Nếu mã này là mã truy cập và có mã làm mới tương ứng, thì mã làm mới cũng sẽ bị thu hồi.
Nếu quá trình thu hồi được xử lý thành công, thì mã trạng thái của phản hồi sẽ là 200
. Đối với các điều kiện lỗi, mã trạng thái 400
sẽ được trả về cùng với một mã lỗi.
Node.js
Để thu hồi mã thông báo theo phương thức lập trình, hãy tạo yêu cầu POST HTTPS tới điểm cuối /revoke
:
const https = require('https'); // Build the string for the POST request let postData = "token=" + userCredential.access_token; // Options for POST request to Google's OAuth 2.0 server to revoke a token let postOptions = { host: 'oauth2.googleapis.com', port: '443', path: '/revoke', method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'Content-Length': Buffer.byteLength(postData) } }; // Set up the request const postReq = https.request(postOptions, function (res) { res.setEncoding('utf8'); res.on('data', d => { console.log('Response: ' + d); }); }); postReq.on('error', error => { console.log(error) }); // Post the request with data postReq.write(postData); postReq.end();
Thông số mã thông báo có thể là mã truy cập hoặc mã làm mới. Nếu mã này là mã truy cập và có mã làm mới tương ứng, thì mã làm mới cũng sẽ bị thu hồi.
Nếu quá trình thu hồi được xử lý thành công, thì mã trạng thái của phản hồi sẽ là 200
. Đối với các điều kiện lỗi, mã trạng thái 400
sẽ được trả về cùng với một mã lỗi.
HTTP/REST (Hệ thống HTTP/REST)
Để thu hồi mã thông báo theo phương thức lập trình, ứng dụng sẽ yêu cầu https://oauth2.googleapis.com/revoke
và đưa mã thông báo đó vào dưới dạng thông số:
curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \ https://oauth2.googleapis.com/revoke?token={token}
Mã này có thể là mã truy cập hoặc mã làm mới. Nếu mã này là mã truy cập và có mã làm mới tương ứng, thì mã làm mới cũng sẽ bị thu hồi.
Nếu quá trình thu hồi được xử lý thành công, thì mã trạng thái HTTP của phản hồi sẽ là 200
. Đối với các điều kiện lỗi, mã trạng thái HTTP 400
sẽ được trả về cùng với một mã lỗi.