Tài liệu này giải thích cách các ứng dụng máy chủ web sử dụng các Thư viện ứng dụng API của Google hoặc các điểm cuối OAuth 2.0 của Google để triển khai OAuth 2.0 cho phép 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, đồng thời 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 để xin phép người dùng lưu trữ tệp trong Google Drive của họ.
Luồng OAuth 2.0 này dành riêng cho việc ủy quyền người dùng. Ứng dụng này được thiết kế cho những ứ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 ủy quyền đúng cách có thể truy cập 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 API Cloud để truy cập dữ liệu dựa trên dự án thay vì dữ liệu theo từng 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 sự cho phép của người dùng.
Thư viện ứng dụng
Các ví dụ theo 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 khách sẽ thực hiện nhiều thao tác mà ứng dụng cần tự xử lý. Ví dụ: tỷ lệ này sẽ 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 URL chuyển hướng chính xác và giúp triển khai trình xử lý chuyển hướng trao đổi mã ủy quyền cho mã truy cập.
Các thư viện ứng dụng API của Google cho các ứng dụng phía máy chủ hiện có sẵn cho những ngôn ngữ sau:
Điều kiện tiên quyết
Bật API cho dự án của bạn
Mọi ứng dụng 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 Danh sách tất 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 bật không hiển thị trong danh sách, hãy sử dụng tính 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 đăng nhập ủy quyền
Bất kỳ ứng dụng nào sử dụng OAuth 2.0 để truy cập API của Google đều phải có thông tin đăng nhập ủy quyền để nhận dạng ứng dụng đó bằng máy chủ OAuth 2.0 của Google. Sau đây là các bước giải thích cách tạo thông tin đăng nhập cho dự án của bạn. Sau đó, các ứng dụng của bạn có thể sử dụng thông tin xác thực để truy cập các 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 OAuth.
- Chọn loại ứng dụng Ứng dụng web.
- Điền thông tin vào biểu mẫu, rồi nhấp vào Tạo. Những ứng dụng sử dụng các ngôn ngữ và khung
như PHP, Java, Python, Ruby và .NET phải chỉ định URI chuyển hướng được ủy quyền. 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ủ quy tắc xác thực của Google.
Để thử nghiệm, bạn có thể chỉ định các URI tham chiếu đến máy cục bộ, chẳng hạn như
http://localhost:8080
. Xin lưu ý rằng tất cả các ví dụ trong tài liệu này 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 của bạn không để lộ mã ủy 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 đã yêu cầu và khả năng có được sự đồng ý của người dùng.
Trước khi bắt đầu triển khai ủ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 sẽ cần quyền truy cập.
Bạn cũng nên yêu cầu quyền truy cập vào phạm vi ủy quyền thông qua một quy trình ủy quyền gia tăng, trong đó ứng dụng của bạn yêu cầu quyền truy cập vào dữ liệu người dùng theo 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 đang 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ể dùng để truy cập vào các API của Google.
Yêu cầu dành riêng cho từng ngôn ngữ
Để chạy bất kỳ mẫu mã nào trong tài liệu này, bạn cần có Tài khoản Google, có kết nối Internet và một trình duyệt web. Nếu bạn đang sử dụng một trong các thư viện ứng dụng API, hãy xem thêm các yêu cầu đối với ngôn ngữ cụ thể bên dưới.
PHP
Để chạy mẫu mã PHP trong tài liệu này, bạn cần:
- PHP 5.4 trở lên khi 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 Soạn thư.
-
Thư viện ứng dụng API Google cho PHP:
php composer.phar require google/apiclient:^2.0
Python
Để chạy mẫu mã Python trong tài liệu này, bạn cần:
- Python 2.6 trở lên
- Công cụ quản lý gói pip.
- Thư viện ứng dụng Python cho các 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 mẫu mã Node.js trong tài liệu này, bạn cần:
- LTS bảo trì, LTS đang hoạt động hoặc bản phát hành hiện tại của Node.js.
-
Ứng dụng Google API Node.js:
npm install googleapis
HTTP/REST (Ngôn ngữ đánh dấu xác nhận bảo mật)
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 đ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 để nhận được sự đồng ý của người dùng để thực hiện yêu cầu API thay mặt người dùng. Ứng dụng của bạn phải có được sự đồng ý đó thì mới có thể thực thi yêu cầu API của Google yêu cầu sự cho phép của người dùng.
Danh sách bên dưới tóm tắt nhanh các bước sau:
- Ứng dụng của bạn xác định các quyền mà ứng dụng cần.
- Ứ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 sẽ quyết định 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 những gì người dùng quyết định.
- Nếu người dùng cấp các quyền được yêu cầu, ứng dụng của bạn sẽ truy xuất mã thông báo cần thiết để thay mặt cho người dùng gửi yêu cầu API.
Bước 1: Đặt thông số ủy quyền
Bước đầu tiên là tạo yêu cầu ủy quyền. Yêu cầu đó sẽ đặt các thông số xác định ứng dụng của bạn và xác định những quyền mà người dùng sẽ được yêu cầu cấp cho ứng dụng của bạn.
- Nếu dùng 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 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 các tham số trên URL đó.
Các thẻ bên dưới xác định những thông số ủy quyền được hỗ trợ cho các ứng dụng máy chủ web. Các ví dụ cụ thể về ngôn ngữ 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 có đặt các thông số đó.
PHP
Đoạn mã bên dưới tạo một đối tượng Google_Client()
để xác định các thông số trong yêu cầu ủy quyền.
Đối tượng đó sử dụng thông tin từ tệp client_secret.json của bạn để xác định ứng dụng. (Xem phần tạo thông tin cấp phép để biết thêm về tệp đó.) Đối tượng này 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. Thao tác 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 đặ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 chỉ đọc, ngoại tuyến 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 thông số | |||||||
---|---|---|---|---|---|---|---|
client_id |
Bắt buộc
ID ứ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 Credentials page API Console. 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 nơi máy chủ API chuyển hướng người dùng sau khi người dùng hoàn thành
luồng ủy 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 ủy quyền của ứng dụng OAuth 2.0 mà bạn đã định cấu hình trong API Consolecủa Credentials page. Nếu giá trị này không khớp với URI chuyển hướng được ủy quyền cho Xin lưu ý rằng lược đồ Để đặt giá trị này bằng 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 được 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ể truy cập thay mặt cho người dùng. Những giá trị này cho biết màn hình đồng ý mà Google hiển thị cho người dùng. 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ó mối quan hệ nghịch đảo giữa số lượng phạm vi đã yêu cầu và khả năng có được sự đồng ý của người dùng. Để đặt giá trị này bằng PHP, hãy gọi hàm $client->addScope(Google_Service_Drive::DRIVE_METADATA_READONLY); Yêu cầu ứng dụng của bạn yêu cầu quyền truy cập vào phạm vi ủy quyền theo 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 theo bối cảnh, thông qua quy trình ủy quyền gia tăng, bạn giúp người dùng dễ dàng hơn để hiểu lý do ứng dụng của bạn cần quyền truy cập vào ứng dụng. |
||||||
access_type |
Nên
Cho biết liệu ứng dụng của bạn có thể làm mới mã 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ị thông số hợp lệ là Đặt giá trị thành Để đặt giá trị này bằng 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 dùng để duy trì trạng thái giữa yêu cầu ủy quyền của bạn và phản hồi của máy chủ ủy 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 thông số này cho nhiều mục đích, chẳng hạn như chuyển hướng người dùng đến
tài nguyên chính xác trong ứng dụng của bạn, gửi nonces và giảm thiểu hành vi giả mạo yêu cầu trên nhiều trang web. Vì Để đặt giá trị này bằng PHP, hãy gọi hàm $client->setState($sample_passthrough_value); |
||||||
include_granted_scopes |
Tùy chọn
Cho phép các ứng dụng dùng thông tin ủ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 bối cảnh. Nếu bạn đặt giá trị của thông số này là Để đặt giá trị này bằng PHP, hãy gọi hàm $client->setIncludeGrantedScopes(true); |
||||||
login_hint |
Tùy chọn
Nếu biết ứng dụng nào đang cố gắng xác thực, ứ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 hóa quy trình đăng nhập bằng cách điền sẵn trường email trong biểu mẫu đăng nhập hoặc bằng cách chọn phiên đăng nhập nhiều tài khoản thích hợp. Đặt giá trị thông số thành địa chỉ email hoặc giá trị nhận dạng Để đặt giá trị này bằng PHP, hãy gọi hàm $client->setLoginHint('None'); |
||||||
prompt |
Tùy chọn
Danh sách lời nhắc có phân biệt chữ hoa chữ thường và được phân tách bằng dấu cách để hiển thị cho người dùng. Nếu bạn không chỉ định tham số này, người dùng sẽ chỉ được nhắc vào lần đầu tiên dự án của bạn yêu cầu quyền truy cập. Hãy xem phần Nhắc lại sự đồng ý để biết thêm thông tin. Để đặt giá trị này bằng PHP, hãy gọi hàm $client->setApprovalPrompt('consent'); Các giá trị có thể là:
|
Python
Đoạn mã sau sử dụng mô-đun google-auth-oauthlib.flow
để tạo
yêu cầu ủy quyền.
Mã này tạo một đối tượng Flow
để 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 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. Thao tác 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 chỉ đọc, ngoại tuyến 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 thông số | |||||||
---|---|---|---|---|---|---|---|
client_id |
Bắt buộc
ID ứ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 Credentials page API Console. 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 nơi máy chủ API chuyển hướng người dùng sau khi người dùng hoàn thành
luồng ủy 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 ủy quyền của ứng dụng OAuth 2.0 mà bạn đã định cấu hình trong API Consolecủa Credentials page. Nếu giá trị này không khớp với URI chuyển hướng được ủy quyền cho Xin lưu ý rằng lược đồ Để đặt giá trị này bằng Python, hãy đặt thuộc tính flow.redirect_uri = 'https://oauth2.example.com/code' |
||||||
scope |
Bắt buộc
Danh sách các phạm vi xác định các tài nguyên mà ứng dụng của bạn có thể truy cập thay mặt cho người dùng. Những giá trị này cho biết màn hình đồng ý mà Google hiển thị cho người dùng. 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ó mối quan hệ nghịch đảo giữa số lượng phạm vi đã yêu cầu và khả năng có được sự đồng ý của người dùng. Trong Python, hãy dùng phương thức mà bạn 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']) Yêu cầu ứng dụng của bạn yêu cầu quyền truy cập vào phạm vi ủy quyền theo 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 theo bối cảnh, thông qua quy trình ủy quyền gia tăng, bạn giúp người dùng dễ dàng hơn để hiểu lý do ứng dụng của bạn cần quyền truy cập vào ứng dụng. |
||||||
access_type |
Nên
Cho biết liệu ứng dụng của bạn có thể làm mới mã 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ị thông số hợp lệ là Đặt giá trị thành Trong Python, hãy đặt thông 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 dùng để duy trì trạng thái giữa yêu cầu ủy quyền của bạn và phản hồi của máy chủ ủy 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 thông số này cho nhiều mục đích, chẳng hạn như chuyển hướng người dùng đến
tài nguyên chính xác trong ứng dụng của bạn, gửi nonces và giảm thiểu hành vi giả mạo yêu cầu trên nhiều trang web. Vì Trong Python, hãy đặt thông số authorization_url, state = flow.authorization_url( access_type='offline', state=sample_passthrough_value, include_granted_scopes='true') |
||||||
include_granted_scopes |
Tùy chọn
Cho phép các ứng dụng dùng thông tin ủ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 bối cảnh. Nếu bạn đặt giá trị của thông số này là Trong Python, hãy đặt thông số authorization_url, state = flow.authorization_url( access_type='offline', include_granted_scopes='true') |
||||||
login_hint |
Tùy chọn
Nếu biết ứng dụng nào đang cố gắng xác thực, ứ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 hóa quy trình đăng nhập bằng cách điền sẵn trường email trong biểu mẫu đăng nhập hoặc bằng cách chọn phiên đăng nhập nhiều tài khoản thích hợp. Đặt giá trị thông số thành địa chỉ email hoặc giá trị nhận dạng Trong Python, hãy đặt thông số authorization_url, state = flow.authorization_url( access_type='offline', login_hint='None', include_granted_scopes='true') |
||||||
prompt |
Tùy chọn
Danh sách lời nhắc có phân biệt chữ hoa chữ thường và được phân tách bằng dấu cách để hiển thị cho người dùng. Nếu bạn không chỉ định tham số này, người dùng sẽ chỉ được nhắc vào lần đầu tiên dự án của bạn yêu cầu quyền truy cập. Hãy xem phần Nhắc lại sự đồng ý để biết thêm thông tin. Trong Python, hãy đặt thông 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 client trong ứng dụng của bạn. Khi định cấu hình đối tượng máy khách, bạn chỉ định những phạm vi mà ứng dụng của bạn cần truy cập, cùng với URL đến điểm cuối xác thực của ứng dụng. Thao tác 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 chỉ đọc, ngoại tuyến 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 sử dụng đối tượng máy 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 ủy quyền và áp dụng mã thông báo truy cập cho các yêu cầu HTTP.
Node.js
Đoạn mã bên dưới tạo một đối tượng google.auth.OAuth2
để xác định các thông số trong yêu cầu ủy 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ã truy cập, bạn phải chuyển hướng họ đến trang đồng ý. Cách tạo URL 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 ủy quyền đầu tiên. Tìm hiểu thêm thông tin
tại đây.
HTTP/REST (Ngôn ngữ đánh dấu xác nhận bảo mật)
Điểm cuối OAuth 2.0 của Google đang ở 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 túy bị từ chối.
Máy chủ ủy quyền của Google hỗ trợ các tham số chuỗi truy vấn sau cho các ứng dụng máy chủ web:
Các thông số | |||||||
---|---|---|---|---|---|---|---|
client_id |
Bắt buộc
ID ứ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 Credentials page API Console. |
||||||
redirect_uri |
Bắt buộc
Xác định nơi máy chủ API chuyển hướng người dùng sau khi người dùng hoàn thành
luồng ủy 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 ủy quyền của ứng dụng OAuth 2.0 mà bạn đã định cấu hình trong API Consolecủa Credentials page. Nếu giá trị này không khớp với URI chuyển hướng được ủy quyền cho Xin lưu ý rằng lược đồ |
||||||
response_type |
Bắt buộc
Xác định điểm cuối của Google OAuth 2.0 có trả về mã ủy 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 được 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ể truy cập thay mặt cho người dùng. Những giá trị này cho biết màn hình đồng ý mà Google hiển thị cho người dùng. 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ó mối quan hệ nghịch đảo giữa số lượng phạm vi đã yêu cầu và khả năng có được sự đồng ý của người dùng. Yêu cầu ứng dụng của bạn yêu cầu quyền truy cập vào phạm vi ủy quyền theo 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 theo bối cảnh, thông qua quy trình ủy quyền gia tăng, bạn giúp người dùng dễ dàng hơn để hiểu lý do ứng dụng của bạn cần quyền truy cập vào ứng dụng. |
||||||
access_type |
Nên
Cho biết liệu ứng dụng của bạn có thể làm mới mã 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ị thông 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 dùng để duy trì trạng thái giữa yêu cầu ủy quyền của bạn và phản hồi của máy chủ ủy 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 thông số này cho nhiều mục đích, chẳng hạn như chuyển hướng người dùng đến
tài nguyên chính xác trong ứng dụng của bạn, gửi nonces và giảm thiểu hành vi giả mạo yêu cầu trên nhiều trang web. Vì |
||||||
include_granted_scopes |
Tùy chọn
Cho phép các ứng dụng dùng thông tin ủ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 bối cảnh. Nếu bạn đặt giá trị của thông số này là |
||||||
login_hint |
Tùy chọn
Nếu biết ứng dụng nào đang cố gắng xác thực, ứ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 hóa quy trình đăng nhập bằng cách điền sẵn trường email trong biểu mẫu đăng nhập hoặc bằng cách chọn phiên đăng nhập nhiều tài khoản thích hợp. Đặt giá trị thông số thành địa chỉ email hoặc giá trị nhận dạng |
||||||
prompt |
Tùy chọn
Danh sách lời nhắc có phân biệt chữ hoa chữ thường và được phân tách bằng dấu cách để hiển thị cho người dùng. Nếu bạn không chỉ định tham số này, người dùng sẽ chỉ được nhắc vào lần đầu tiên dự án của bạn yêu cầu quyền truy cập. Hãy xem phần 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à ủy 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 ủy quyền gia tăng, bước này cũng xảy ra khi ứng dụng của bạn lần đầu tiê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 ủy 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 tới
auth_uri
.
Node.js
-
Sử dụng URL đã tạo
authorizationUrl
từ phương thức Bướ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 tới
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 đó.
Máy chủ OAuth 2.0 của Google sẽ xác thực người dùng và nhận được sự đồng ý của người dùng để ứng dụng của bạn truy cập các phạm vi đã yêu cầu. Phản hồi sẽ được gửi trở lại ứng dụng của bạn bằng cách sử dụng URL chuyển hướng mà bạn đã chỉ định.
Bước 3: Google nhắc người dùng đồng ý
Trong 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 đồng ý, trong đó hiển thị tên ứng dụng và các dịch vụ API của Google mà ứng dụng đó đang yêu cầu quyền truy cập bằng thông tin ủy quyền của người dùng và bản tóm tắt các phạm vi quyền truy cập sẽ được 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 theo yêu cầu của bạn hoặc từ chối yêu cầu.
Ứng dụng của bạn không cần làm gì trong giai đoạn này vì đang chờ phản hồi của máy chủ OAuth 2.0 của Google cho biết liệu có cấp quyền truy cập nào không. Phản hồi đó sẽ được giải thích trong bước sau.
Lỗi
Các yêu cầu đến điểm cuối ủy quyền OAuth 2.0 của Google có thể hiển thị các thông báo lỗi mà người dùng thấy được thay vì các quy trình xác thực và ủy quyền dự kiến. Bên dưới là các mã lỗi phổ biến và cách giải quyết được đề xuất.
admin_policy_enforced
Tài khoản Google không thể ủy quyền 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 của họ. 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 nội dung & của bên thứ ba; các ứng dụng nội bộ truy cập vào dữ liệu trong Google Workspace để biết thêm thông tin về cách quản trị viên có thể hạn chế quyền truy cập vào tất cả các phạm vi hoặc phạm vi nhạy cảm và bị hạn chế cho đến khi quyền truy cập được cấp rõ ràng vào mã ứng dụng OAuth của bạn.
disallowed_useragent
Điểm cuối ủy quyền được hiển thị bên trong tác nhân người dùng đã nhúng theo Chính sách OAuth 2.0 của Google.
Android
Nhà phát triển Android có thể nhận được thông báo lỗi này khi mở yêu cầu ủy 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ác nhà phát triển web có thể gặp lỗi này khi ứng dụng Android mở một đường liên kết web chung trong một tác nhân người dùng được nhúng và người dùng chuyển đến điểm cuối ủy quyền OAuth 2.0 của Google trên trang web của bạn. Nhà phát triển nên cho phép mở đườ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 (bao gồm 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 Các thẻ tùy chỉnh Android cũng là một tùy chọn được hỗ trợ.
iOS
Các nhà phát triển iOS và macOS có thể gặp lỗi này khi mở các yêu cầu ủy quyền trong
WKWebView
.
Thay vào đó, nhà phát triển nên sử dụng các thư viện dành cho iOS như Đăng nhập bằng Google dành cho iOS hoặc AppAuth for iOS của OpenID Foundation.
Các 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 một tác nhân người dùng được nhúng và người dùng chuyển đến điểm cuối ủy quyền OAuth 2.0 của Google trên 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, bao gồm 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 OAuth trong yêu cầu 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ề tùy 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 đồng ý OAuth.
redirect_uri_mismatch
redirect_uri
được chuyển trong yêu cầu ủy quyền không khớp với URI chuyển hướng được ủy quyền cho mã ứng dụng OAuth. Xem lại các URI chuyển hướng được ủy quyền trong
Google API Console Credentials page.
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 quyền truy cập của ứng dụng bằng cách 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ột mã ủy quyền. Nếu người dùng không phê duyệt yêu cầu, thì phản hồi sẽ chứa một thông báo lỗi. Mã ủy quyền hoặc thông báo lỗi được trả về máy chủ web sẽ xuất hiện trên chuỗi truy vấn, như minh họa dưới đây:
Phản hồi lỗi:
https://oauth2.example.com/auth?error=access_denied
Phản hồi mã ủy 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. URL này yêu cầu quyền chỉ có quyền đọc để xem siêu dữ liệu cho 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 thành 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 tệp tại địa chỉ đó. Bước tiếp theo sẽ cung cấp thêm thông tin chi tiết về 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ã ủy 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ã ủy quyền, máy chủ có thể trao đổi mã ủy quyền để lấy mã truy cập.
PHP
Để trao đổi mã ủy 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ủ ủy quyền. Sau đó, hãy sử dụng phương thức flow.fetch_token
để trao đổi mã ủy 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ã ủy 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ã ủy 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 (Ngôn ngữ đánh dấu xác nhận bảo mật)
Để trao đổi mã ủy 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:
Trường | |
---|---|
client_id |
Mã ứng dụng 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ã ủy quyền trả về từ yêu cầu ban đầu. |
grant_type |
Như đã xác định trong quy cách OAuth 2.0, bạn phải đặt giá trị của trường này là authorization_code . |
redirect_uri |
Một trong các URI chuyển hướng được liệt kê cho dự án của bạn trong
API Console
Credentials page cho
client_id đã cho. |
Đoạn mã sau đây hiển thị 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ã 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 của máy chủ ủy quyền của Google.
Phản hồi chứa các trường sau:
Trường | |
---|---|
access_token |
Mã thông báo mà ứng dụng của bạn gửi để ủy quyền một yêu cầu API của Google. |
expires_in |
Thời gian còn lại của mã truy cập tính bằng giây. |
refresh_token |
Mã thông báo mà bạn có thể sử dụng để lấy mã truy cập mới. Mã làm mới sẽ có hiệu lực 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ủ ủy quyền của Google.
|
scope |
Phạm vi truy cập do 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 và phân biệt chữ hoa chữ thường. |
token_type |
Loại mã thông báo được trả về. Lúc này, 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" }
Gọi API Google
PHP
Sử dụng mã truy cập để gọi API của Google bằng cách hoàn thành các bước sau:
- Nếu bạn cần áp dụng mã truy cập cho đố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 hoạt động của người dùng), hãy sử dụng phương thứcsetAccessToken
:$client->setAccessToken($access_token);
- Tạo đố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 dựng cho API mà bạn muốn gọi. Ví dụ: để gọi API Drive:$drive = new Google_Service_Drive($client);
- Gửi yêu cầu tới dịch vụ API bằng giao diện do đối tượng dịch vụ cung cấp.
Ví dụ: để liệt kê các tệp trong Google Drive của người dùng đã xác thực:
$files = $drive->files->listFiles(array())->getItems();
Python
Sau khi nhận được mã truy cập, ứng dụng của bạn có thể sử dụng mã đó để ủy quyền 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 đăng nhập ủy quyền dành riêng cho 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 ủy quyền.
- Tạo đố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
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 đăng nhập 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)
- Gửi yêu cầu tới dịch vụ API bằng giao diện do đối tượng dịch vụ cung cấp.
Ví dụ: để liệt kê các tệp trong Google Drive của người dùng đã xác thực:
files = drive.files().list().execute()
Ruby
Hãy 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:
- Tạo đố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 cho dịch vụ này:
drive.authorization = auth_client
- Gửi yêu cầu tới dịch vụ API bằng giao diện do đối tượng dịch vụ cung cấp.
Ví dụ: để liệt kê các 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ể cung cấp ủy quyền cho 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 lấy mã truy cập và đặt mã đó vào đối tượng OAuth2
, hãy dùng đối tượng này để gọi API của Google. Ứng dụng của bạn có thể dùng mã đó để ủy quyền 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. Tạo đố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 (Ngôn ngữ đánh dấu xác nhận bảo mật)
Sau khi ứng dụng của bạn nhận được mã truy cập, bạn có thể sử dụng mã đó để gọi điện đến API Google
thay mặt cho một
tài khoản người dùng nhất định nếu(các) phạm vi quyền truy cập mà API yêu cầu đã cấp. Để làm điều này, hãy đưa mã truy cập vào yêu cầu API bằng cách thêm thông số truy vấn access_token
hoặc tiêu đề Authorization
tiêu đề HTTP Bearer
. Khi có thể, bạn nên dùng tiêu đề HTTP vì các chuỗi truy vấn 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 thư viện ứng dụng để thiết lập lệnh gọi đến API 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 này tại OAuth 2.0 Playground.
Ví dụ về HTTP GET
Lệnh gọi đến điểm cuối
drive.files
(API Drive Drive) bằng cách 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 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 thông 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 tra các lệnh này bằng ứng dụng dòng lệnh curl
. Sau đây là ví dụ về cách sử dụng tùy 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 sẽ in danh sách các tệp theo định dạng JSON trong Google Drive của người dùng sau khi người dùng xác thực và đồng ý cho phép ứng dụng truy cập vào siêu dữ liệu Drive của người dùng đó.
PHP
Để chạy ví dụ này:
- Trong API Console, hãy thêm URL của máy cục bộ vào danh sách URL chuyển hướng. Ví dụ: thêm
http://localhost:8080
. - Tạo thư mục mới và thay đổi 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.0
- Tạo các tệp
index.php
vàoauth2callback.php
có nội dung bên dưới. - Hãy chạy ví dụ này với một máy chủ web được định cấu hình để phân phát PHP. Nếu sử dụng PHP 5.4 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. Ứng dụng này
chạy một ứng dụng web tại http://localhost:8080
cho phép bạn kiểm tra 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:
- Thử nghiệm yêu cầu API: Đường liên kết này trỏ đến một trang cố thực hiện yêu cầu API mẫu. Nếu cần thiết, quy trình này sẽ bắt đầu quy trình ủy 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 đưa người dùng đến thông qua quy trình ủy quyền. Ứng dụng này yêu cầu quyền thay mặt cho người dùng gửi yêu cầu API được ủy quyền.
- Thu hồi thông tin đăng nhập hiện tại: Đường liên kết này trỏ đến một trang thu hồi quyền mà người dùng đã cấp cho ứng dụng.
- Xóa thông tin xác thực của phiên hoạt động bình luận: Đường liên kết này sẽ xóa thông tin đăng nhập ủy quyền được lưu trữ trong phiên Bình đó. Điều này cho phép bạn thấy đ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. Thẻ này cũng cho phép bạn xem phản hồi của 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 cấp phép cho yêu cầu bằng mã thông báo truy cập bị 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:
-
Trong API Console, hãy thêm URL của máy cục bộ vào danh sách URL chuyển hướng. Ví dụ: thêm
http://localhost
. - Đảm bảo bạn đã cài đặt LTS, bảo mật LTS hoặc bản phát hành hiện tại của Node.js.
-
Tạo thư mục mới và thay đổi 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 tệp
main.js
có nội dung bên dưới. -
Chạy ví dụ:
node .\main.js
main.js (.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 (Ngôn ngữ đánh dấu xác nhận bảo mật)
Ví dụ về Python này sử dụng khung Flask và thư viện Yêu cầu để chứng minh 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()
Quy tắc xác thực URI chuyển hướng
Google áp dụng những quy tắc xác thực sau đây để 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ủ những quy tắc này. Xem RFC 3986 mục 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, được đề cập ở bên dưới.
Các quy tắc xác thực | |
---|---|
Lược đồ |
URI chuyển hướng phải dùng lược đồ HTTPS, không phải HTTP thuần. Các URI của máy chủ cục bộ (bao gồm các URI địa chỉ IP của máy chủ cục bộ) không được áp dụng cho quy tắc này. |
Máy chủ lưu trữ |
Máy chủ không thể là địa chỉ IP thô. Địa chỉ IP máy chủ cục bộ được miễn khỏi 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ì URL chuyển hướng đó phải chứa “/google-callback/” trong đường dẫn của ứng dụng 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ụ thông tin người dùng. |
Đường dẫn |
URI chuyển hướng không được chứa đường dẫn truyền tải (còn gọi là theo dõ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ự nhất định, bao gồm:
|
Ủy quyền gia tăng
Trong giao thức OAuth 2.0, ứng dụng của bạn yêu cầu ủy quyền truy cập vào các tài nguyên mà chúng tôi xác định theo phạm vi. Việc yêu cầu ủy quyền cho các tài nguyên tại thời điểm bạn cần sẽ được coi là phương pháp hay nhất cho trải nghiệm người dùng. Để bật tính năng này, máy chủ ủy quyền của Google sẽ hỗ trợ việc ủy quyền gia tăng. Tính năng này cho phép bạn yêu cầu các phạm vi khi cần thiết và nếu người dùng cấp quyền cho phạm vi mới, sẽ trả về một mã ủy quyền có thể được đổ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 nhạc kết hợp có thể cần rất ít tài nguyên tại thời điểm đăng nhập, và có thể sẽ không cần gì ngoài tên của người đang đăng nhập. Tuy nhiên, bạn phải 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 sẽ cảm thấy tự nhiên nếu họ chỉ được yêu cầu cấp quyền truy cập vào Google Drive vào thời điểm thực sự cần ứng dụng.
Trong trường hợp này, vào 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 việc đă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 ủy quyền gia tăng, bạn phải hoàn thành quy trình bình thường để yêu cầu mã truy cập, nhưng hãy đảm bảo yêu cầu ủy quyền 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 tránh phải quản lý nhiều mã truy cập.
Các quy tắc sau đây áp dụng cho mã truy cập nhận được từ một ủy quyền gia tăng:
- Bạn có thể dùng mã thông báo này để truy cập vào các tài nguyên tương ứng với mọi phạm vi được đưa vào sự ủy quyền kết hợp mới.
- Khi bạn sử dụng mã làm mới cho lệnh ủy quyền kết hợp để lấy mã truy cập, mã truy cập này đại diện cho mã ủy quyền kết hợp và có thể dùng cho bất kỳ giá trị
scope
nào trong phản hồi. - Quy trình ủy quyền kết hợp bao gồm tất cả các phạm vi mà người dùng được cấp cho dự án API ngay cả khi các ứng dụng khác nhau yêu cầu cấp quyền. 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 dành cho máy tính của một ứng dụng, sau đó cấp một phạm vi khác cho ứng dụng đó thông qua ứng dụng dành cho thiết bị di động, thì lệnh ủy 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ã thông báo đại diện cho một lệnh ủy quyền kết hợp, quyền truy cập vào tất cả các phạm vi ủy 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ẫu mã dành riêng cho ngôn ngữ trong Bước 1: Thiết lập tham số ủy 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 hình thức ủy quyền gia tăng. Các mã mẫu bên dưới cũng hiển thị mã mà bạn cần thêm để sử dụng tùy chọn ủy quyền gia tăng.
PHP
$client->setIncludeGrantedScopes(true);
Python
Trong Python, hãy đặt đối số từ khóa include_granted_scopes
thành true
để đảm bảo rằng yêu cầu ủy quyền có các phạm vi đã cấp trước đó. Có thể include_granted_scopes
sẽ không phải là đối số từ khóa chỉ mà bạn đặt, như 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 (Ngôn ngữ đánh dấu xác nhận bảo mật)
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ã thông báo truy cập (truy cập ngoại tuyến)
Mã thông báo truy cập sẽ hết hạn theo định kỳ và trở thành thông tin đăng nhập 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 về quyền (bao gồm cả khi người dùng không hiện diện) 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ã đó.
- Nếu bạn sử dụng Thư viện ứng dụng API của Google, đối tượng máy khách sẽ làm mới mã thông báo truy cập này, 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ủ ủy quyền của Google sẽ trả về mã làm mới khi bạn đổi mã ủy quyền để có 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ể sử dụng mã làm mới để lấy mã truy cập mới.
Yêu cầu quyền truy cập ngoại tuyến là yêu cầu bắt buộc đối với mọi ứng dụng cần truy cập vào API của 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 hiện thao tác vào những thời điểm đã xác định trước cần phải làm mới mã truy cập của ứng dụng khi người dùng không có mặt. Kiểu truy cập mặc định được gọi là online
.
Các ứng dụng web, ứng dụng đã cài đặt và thiết bị phía máy chủ đều nhận được mã thông báo làm mới trong quá trình ủy quyền. Mã thông báo làm mới thường không được dùng trong các ứng dụng web (JavaScript) phía máy khách.
PHP
Nếu ứng dụng của bạn cần quyền truy cập khi không có mạng vào một API 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 để truy cập API Google thay mặt cho người dùng khi người dùng không có kết nối mạng. Đối tượng máy khách sẽ làm mới mã truy cập nếu cần.
Python
Trong Python, hãy đặt đối số từ khóa access_type
thành offline
để đảm bảo rằng bạn sẽ 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. Có thể access_type
sẽ không phải là đối số từ khóa chỉ mà bạn đặt, như minh họa 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')
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 để truy cập API Google thay mặt cho người dùng khi người dùng không có kết nối mạng. Đối tượng máy khách sẽ làm mới mã truy cập nếu cần.
Ruby
Nếu ứng dụng của bạn cần quyền truy cập khi không có mạng vào một API 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 để truy cập API Google thay mặt cho người dùng khi người dùng không có kết nối mạng. Đối tượng máy khách sẽ làm mới mã truy cập nếu cần.
Node.js
Nếu ứng dụng của bạn cần quyền truy cập khi không có mạng vào một API 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 để truy cập API Google thay mặt cho người dùng khi người dùng không có kết nối mạng. Đối tượng máy khách sẽ làm mới mã truy cập nếu cần.
Mã thông báo truy cập sẽ hết hạn. Thư viện này sẽ tự động dùng mã làm mới để lấy mã truy cập mới nếu mã đó sắp hết hạn. Một cách dễ dàng để đảm bảo bạn luôn lưu trữ các mã thông báo mới 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ỉ diễn ra trong lần ủy quyền đầu tiên và bạ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 đã cấp cho ứng dụng quyền yêu cầu lại mà không cần đặt các quy tắc ràng buộc thích hợp để nhận mã làm mới, bạn sẽ cần phải cho phép lại ứng dụng để nhận mã làm mới.
Để đặt refresh_token
sau, bạn có thể sử dụng phương thức setCredentials
:
oauth2Client.setCredentials({ refresh_token: `STORED_REFRESH_TOKEN` });
Sau khi máy khách có mã làm mới, mã truy cập sẽ được lấy tự động và làm mới trong lệnh gọi tiếp theo tới API.
HTTP/REST (Ngôn ngữ đánh dấu xác nhận bảo mật)
Để làm mới mã truy cập, ứng dụng của bạn sẽ gửi một yêu cầu POST
HTTPS đến máy chủ ủy quyền của Google (https://oauth2.googleapis.com/token
) trong đó có các thông số sau:
Trường | |
---|---|
client_id |
Mã ứng dụng được lấy 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 quy cách OAuth 2.0, bạn phải đặt giá trị của trường này là refresh_token . |
refresh_token |
Mã làm mới sẽ trả về từ sàn giao dịch mã ủy quyền. |
Đoạn mã sau đây hiển thị 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 cấp cho ứng dụng, thì máy chủ mã thông báo sẽ trả về một đố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 sẽ 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 khác cho mỗi người dùng trên tất cả khách hàng. Bạn nên lưu các mã thông báo làm mới trong bộ nhớ dài hạn và tiếp tục sử dụng các mã thông báo đó, miễn là các mã này 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, ứng dụng có thể gặp phải các giới hạn này. Trong trường hợp đó, các mã thông báo làm mới cũ hơn 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 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 phần Xóa quyền truy cập vào trang web hoặc ứng dụng của trang web bên thứ ba và amp; các ứng dụng có quyền truy cập vào tài khoản của bạn tài liệu hỗ trợ để biết thêm thông tin.
Ứng dụng cũng có thể thu hồi quyền truy cập được cấp theo phương thức lập trình. Tính năng thu hồi có lập trình đóng vai trò quan trọng trong các trường hợp người dùng hủy đăng ký, xoá một ứng dụng hoặc các tài nguyên API mà một ứng dụng yêu cầu đã thay đổi đáng kể. Nói cách khác, quy trình xoá có thể chứa một yêu cầu API để đảm bảo những quyền trước đây đã cấp cho ứng dụng này bị xoá.
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 bằng cách lập trình, hãy gửi yêu cầu tới https://oauth2.googleapis.com/revoke
, trong đó 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 bằng cách lập trình, hãy thực hiện 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ã mới, 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 điều kiện lỗi, mã trạng thái 400
được trả về cùng với mã lỗi.
Node.js
Để thu hồi mã thông báo theo phương thức lập trình, hãy thực hiện yêu cầu POST HTTPS đến đ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ã mới, 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 điều kiện lỗi, mã trạng thái 400
được trả về cùng với mã lỗi.
HTTP/REST (Ngôn ngữ đánh dấu xác nhận bảo mật)
Để thu hồi mã thông báo theo phương thức lập trình, ứng dụng của bạn sẽ yêu cầu
https://oauth2.googleapis.com/revoke
và đưa mã thông báo làm 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ã mới, 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 điều kiện lỗi, mã trạng thái HTTP 400
sẽ được trả về
cùng với mã lỗi.