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 Google Các điểm cuối của OAuth 2.0 để triển khai việc uỷ quyền của OAuth 2.0 để truy cập YouTube Analytics API hoặc API Báo cáo của YouTube.
OAuth 2.0 cho phép người dùng chia sẻ dữ liệu cụ thể với ứng dụng trong khi vẫn giữ cho tên người dùng, mật khẩu và các thông tin khác ở chế độ riêng tư. Ví dụ: một ứng dụng có thể dùng OAuth 2.0 để có được quyền để truy xuất dữ liệu YouTube Analytics của kênh.
Quy trình OAuth 2.0 này dành riêng cho việc cho phép 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. Một máy chủ web được uỷ quyền đúng cách ứng dụng 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 thường xuyên 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 cụ thể về người dùng. Các ứng dụng trên máy chủ web có thể sử dụng dịch vụ tài khoản cùng với sự cho phép của người dùng.
- YouTube Analytics API không hỗ trợ quy trình tài khoản dịch vụ.
- API Báo cáo của YouTube chỉ hỗ trợ quy trình tài khoản dịch vụ
dành cho những chủ sở hữu nội dung trên YouTube sở hữu và quản lý nhiều kênh YouTube.
Cụ thể, chủ sở hữu nội dung có thể sử dụng tài khoản dịch vụ trong các yêu cầu API
để đặt một giá trị cho yêu cầu
onBehalfOfContentOwner
.
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 Uỷ 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 khác cho ngôn ngữ của bạn.
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ì ứng dụng thư viện thực hiện nhiều thao tác mà ứng dụng cần tự xử lý. Cho ví dụ: mã xác định thời điểm ứng dụng có thể sử dụng hoặc làm mới mã truy cập đã lưu trữ cũng như khi đơn đăng ký phải có được sự đồng ý. Thư viện ứng dụng cũng tạo lệnh chuyển hướng chính xác URL và giúp triển khai trình xử lý chuyển hướng trao đổi mã uỷ quyền lấy mã truy cập.
Thư viện ứng dụng API của Google dành 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 của bạn
Bất kỳ ứng dụng nào gọi Google API đều cần 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.
- Sử dụng trang Thư viện để tìm và bật API YouTube Analytics và API Báo cáo của YouTube. Nhiều ứng dụng truy xuất dữ liệu YouTube Analytics cũng tương thích với YouTube Data API. Tìm mọi API khác mà ứng dụng của bạn sẽ sử dụng và bật các API đó.
Tạo thông tin xác thực cho phép
Mọi ứng dụng sử dụng OAuth 2.0 để truy cập API Google đều phải có thông tin xác thực uỷ quyền xác định ứng dụng tới máy chủ OAuth 2.0 của Google. Các bước sau đây sẽ giải thích cách tạo thông tin xác thực cho dự án của bạn. Sau đó, ứng dụng của bạn có thể sử dụng thông tin xác thực để truy cập 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 Web application (Ứng dụng web).
- Điền vào biểu mẫu rồi nhấp vào Tạo. Ứng dụng sử dụng ngôn ngữ và khung
như PHP, Java, Python, Ruby và .NET phải chỉ định URI chuyển hướng được phép. Chiến lược phát hành đĩa đơ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 đến. Các
điểm cuối 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 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ã uỷ quyền cho các tài nguyên khác trên .
Sau khi tạo thông tin đăng nhập, hãy tải tệp client_secret.json xuống từ API Console. Lưu trữ tệp an toàn ở vị trí chỉ mà ứng dụng của bạn 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 mà ứng dụng cần trong khi cho phép người dùng kiểm soát lượng truy cập mà họ cấp cho ứng dụng của bạn. Do đó, có thể là mối quan hệ nghịch đảo giữa số phạm vi được yêu cầu và khả năng lấy sự đồng ý của người dùng.
Trước khi bắt đầu triển khai việc uỷ 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ủa bạn 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 đó đơn đăng ký 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.
API YouTube Analytics sử dụng các phạm vi sau:
Phạm vi | |
---|---|
https://www.googleapis.com/auth/youtube | Quản lý tài khoản YouTube của bạn |
https://www.googleapis.com/auth/youtube.readonly | Xem tài khoản YouTube của bạn |
https://www.googleapis.com/auth/youtubepartner | Xem và quản lý nội dung cũng như nội dung liên quan của bạn trên YouTube |
https://www.googleapis.com/auth/yt-analytics-monetary.readonly | Xem báo cáo YouTube Analytics bằng tiền và phi tiền tệ cho nội dung YouTube của bạn |
https://www.googleapis.com/auth/yt-analytics.readonly | Xem báo cáo YouTube Analytics cho nội dung YouTube của bạn |
API Báo cáo của YouTube sử dụng các phạm vi sau:
Phạm vi | |
---|---|
https://www.googleapis.com/auth/yt-analytics-monetary.readonly | Xem báo cáo YouTube Analytics bằng tiền và phi tiền tệ cho nội dung YouTube của bạn |
https://www.googleapis.com/auth/yt-analytics.readonly | Xem báo cáo YouTube Analytics cho nội dung YouTube của bạn |
Tài liệu về Phạm vi API của OAuth 2.0 chứa thông tin đầy đủ danh sách phạm vi mà bạn có thể dùng để truy cập API của Google.
Yêu cầu theo ngôn ngữ cụ thể
Để chạy bất kỳ mã mẫu nào trong tài liệu này, bạn cần có Tài khoản Google, quyền truy cập vào 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 theo các yêu cầu ngôn ngữ cụ thể bên dưới.
PHP
Để chạy mã mẫu PHP trong tài liệu này, bạn cần có:
- PHP 5.6 trở lên khi đã cài đặt giao diện dòng lệnh (CLI) và phần mở rộng JSON.
- Công cụ quản lý phần phụ thuộc Composer.
-
Thư viện ứng dụng API của Google cho PHP:
composer require google/apiclient:^2.10
Python
Để chạy mã mẫu Python trong tài liệu này, bạn cần có:
- Python 2.6 trở lên
- Công cụ quản lý gói pip.
- Thư viện ứng dụng API của Google dành cho Python:
pip install --upgrade google-api-python-client
google-auth
,google-auth-oauthlib
vàgoogle-auth-httplib2
để uỷ quyền cho 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 mã mẫu Ruby trong tài liệu này, bạn cần có:
- Ruby 2.6 trở lên
-
Thư viện xác thực của Google cho Ruby:
gem install googleauth
-
Khung ứng dụng web Sinatra Ruby.
gem install sinatra
Node.js
Để chạy mã mẫu Node.js trong tài liệu này, bạn cần có:
- LTS bảo trì, LTS đang hoạt động hoặc bản phát hành Node.js hiện tại.
-
Ứng dụng Node.js API của Google:
npm install googleapis crypto express express-session
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 OAuth 2.0 điểm cuối.
Lấy mã truy cập OAuth 2.0
Các bước sau đây cho biết cách ứng dụng của bạn tương tác với máy chủ OAuth 2.0 của Google để lấy sự đồng ý của người dùng để thực hiện yêu cầu API thay mặt cho người dùng đó. Ứng dụng của bạn phải có trước khi có thể thực thi yêu cầu API của Google cần người dùng cho phép.
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 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 quyền truy cập.
- Người dùng sẽ quyết định xem 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 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 để đưa ra yêu cầu API thay mặt người dùng.
Bước 1: Đặt tham số uỷ quyền
Bước đầu tiên là tạo yêu cầu uỷ quyền. Yêu cầu đó đặt ra các tham số xác định ứng dụng của bạn và xác định các quyền mà người dùng sẽ được yêu cầu cấp ứng dụng của bạn.
- Nếu dùng một thư viện ứng dụng của Google để xác thực và uỷ quyền OAuth 2.0, bạn 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 giá trị trên URL đó.
Các thẻ bên dưới xác định các tham số cấp quyền được hỗ trợ cho các ứng dụng máy chủ web. Chiến lược phát hành đĩa đơn các ví dụ theo ngôn ngữ cụ thể cũng cho biết cách sử dụng thư viện ứng dụng hoặc thư viện uỷ quyền để định cấu hình một đối tượng sẽ đặt các tham số đó.
PHP
Đoạn mã dưới đây tạo một đối tượng Google\Client()
, đối tượng này xác định
trong yêu cầu uỷ quyền.
Đối tượng đó sử dụng thông tin từ tệp client_secret.json của bạn để xác định
. (Xem bài viết tạo thông tin xác thực cho phép để tìm hiểu 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 tới đ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 đặt access_type
(không bắt buộc) và
Tham số include_granted_scopes
.
Ví dụ: để yêu cầu quyền truy cập ngoại tuyến để truy xuất YouTube Analytics của người dùng báo cáo:
$client = new Google\Client(); // Required, call the setAuthConfig function to load authorization credentials from // client_secret.json file. $client->setAuthConfig('client_secret.json'); // Required, to set the scope value, call the addScope function $client->addScope(Google_Service_YouTubeAnalytics::YT_ANALYTICS_READONLY); // Required, call the setRedirectUri function to specify a valid redirect URI for the // provided client_id $client->setRedirectUri('http://' . $_SERVER['HTTP_HOST'] . '/oauth2callback.php'); // Recommended, 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'); // Recommended, call the setState function. Using a state value can increase your assurance that // an incoming connection is the result of an authentication request. $client->setState($sample_passthrough_value); // Optional, if your application knows which user is trying to authenticate, it can use this // parameter to provide a hint to the Google Authentication Server. $client->setLoginHint('hint@example.com'); // Optional, call the setPrompt function to set "consent" will prompt the user for consent $client->setPrompt('consent'); // Optional, call the setIncludeGrantedScopes function with true to enable incremental // authorization $client->setIncludeGrantedScopes(true);
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
. Đối tượng này nhận dạng ứ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
tạo thông tin xác thực cho phé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 tới
điểm cuối xác thực, sẽ xử lý phản hồi từ máy chủ OAuth 2.0 của Google. Cuối cùng, mã
đặt các tham số access_type
và include_granted_scopes
không bắt buộc.
Ví dụ: để yêu cầu quyền truy cập ngoại tuyến để truy xuất YouTube Analytics của người dùng báo cáo:
import google.oauth2.credentials import google_auth_oauthlib.flow # Required, call the from_client_secrets_file method to retrieve the client ID from a # client_secret.json file. The client ID (from that file) and access scopes are required. (You can # also use the from_client_config method, which passes the client configuration as it originally # appeared in a client secrets file but doesn't access the file itself.) flow = google_auth_oauthlib.flow.Flow.from_client_secrets_file( 'client_secret.json', scopes=['https://www.googleapis.com/auth/yt-analytics.readonly']) # Required, 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( # Recommended, 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', # Optional, enable incremental authorization. Recommended as a best practice. include_granted_scopes='true', # Optional, if your application knows which user is trying to authenticate, it can use this # parameter to provide a hint to the Google Authentication Server. login_hint='hint@example.com', # Optional, set prompt to 'consent' will prompt the user for consent prompt='consent')
Ruby
Sử dụng tệp client_secrets.json mà bạn đã tạo để định cấu hình đối tượng ứng dụng trong . Khi định cấu hình một đối tượng ứng dụng, bạn sẽ chỉ định các phạm vi mà ứng dụng cần cùng với URL tới đ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 qua máy chủ OAuth 2.0.
Ví dụ: để yêu cầu quyền truy cập ngoại tuyến để truy xuất YouTube Analytics của người dùng báo cáo:
require 'google/apis/youtube_analytics_v1' require "googleauth" require 'googleauth/stores/redis_token_store' client_id = Google::Auth::ClientId.from_file('/path/to/client_secret.json') scope = 'https://www.googleapis.com/auth/yt-analytics.readonly' token_store = Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new) authorizer = Google::Auth::WebUserAuthorizer.new(client_id, scope, token_store, '/oauth2callback')
Ứ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ã sau đây tạo một đối tượng google.auth.OAuth2
, đối tượng này xác định
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. Người nhận hãy yêu cầu người dùng cấp quyền để truy xuất mã truy cập, rồi bạn sẽ chuyển hướng họ đến trang đồng ý. Cách tạo URL trang đồng ý:
const {google} = require('googleapis'); const crypto = require('crypto'); const express = require('express'); const session = require('express-session'); /** * 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 secure random state value. const state = crypto.randomBytes(32).toString('hex'); // Store state in the session req.session.state = state; // 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, // Include the state parameter to reduce the risk of CSRF attacks. state: state });
Lưu ý quan trọng – refresh_token
chỉ được trả về vào ngày đầu tiên
uỷ quyền. Thông tin chi tiết
tại đây.
HTTP/REST
Điểm cuối OAuth 2.0 của Google nằm tại https://accounts.google.com/o/oauth2/v2/auth
. Chiến dịch này
chỉ có thể truy cập vào điểm cuối 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 cho web ứng dụng máy chủ:
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 nơi 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 phép cho
ứng dụng OAuth 2.0 mà bạn đã định cấu hình trong
API Console
Credentials pageNếu giá trị này không khớp với
URI chuyển hướng được uỷ quyền cho 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ị tham số thành |
||||||||||||||||||
scope |
Bắt buộc
Đáp phân tách bằng dấu cách danh sách phạm vi xác định tài nguyên mà ứng dụng của bạn có thể truy cập trên thay mặt cho người dùng. Các giá trị này cho biết màn hình xin phép 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 những tài nguyên mà ứng dụng cần đồng thời vẫn cho phép người dùng kiểm soát lượng quyền truy cập mà họ cấp cho . Như vậy, có mối quan hệ nghịch đảo giữa số phạm vi được yêu cầu và khả năng có được sự đồng ý của người dùng. API YouTube Analytics sử dụng các phạm vi sau:
API Báo cáo của YouTube sử dụng các phạm vi sau:
Tài liệu về Phạm vi API của OAuth 2.0 cung cấp danh sách đầy đủ các phạm vi mà bạn có thể dùng để truy cập các API của Google. Ứng dụng của bạn nên yêu cầu quyền truy cập vào phạm vi uỷ 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 uỷ quyền gia tăng, bạn giúp người dùng dễ dàng hiểu 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. |
||||||||||||||||||
access_type |
Recommended (Nên dùng)
Cho biết liệu ứng dụng của bạn có thể làm mới mã truy cập khi không có người dùng hay không
trên trình duyệt. Giá trị thông số hợp lệ là Thiết lập giá trị thành |
||||||||||||||||||
state |
Recommended (Nên dùng)
Chỉ định bất kỳ giá trị chuỗi nào mà ứng dụng của bạn 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 thông số này cho một số mục đích, chẳng hạn như hướng người dùng đến
tài nguyên chính xác trong ứng dụng, gửi số chỉ dùng một lần và giảm thiểu yêu cầu trên nhiều trang web
giả mạo. Vì có thể đoán được |
||||||||||||||||||
include_granted_scopes |
Không bắt buộc
Cho phép các ứng dụng sử dụng chế độ uỷ quyền gia tăng để yêu cầu quyền truy cập vào các
phạm vi theo ngữ cảnh. Nếu bạn đặt giá trị của thông số này thành |
||||||||||||||||||
enable_granular_consent |
Không bắt buộc
Giá trị mặc định là Khi Google bật các quyền chi tiết cho một ứng dụng, tham số này sẽ không không còn tác dụng. |
||||||||||||||||||
login_hint |
Không bắt buộc
Nếu biết người 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 hoá 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 một địa chỉ email hoặc giá trị nhận dạng |
||||||||||||||||||
prompt |
Không bắt buộc
Danh sách câu lệnh, phân tách bằng dấu cách, phân biệt chữ hoa chữ thường để trình bày cho người dùng. Nếu 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. Xem Nhắc tôi đồng ý lại để biết thêm thông tin. Các giá trị có thể là:
|
Bước 2: Chuyển hướng tới 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 quá trình xác thực và quy trình 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. Trong trường hợp uỷ quyền gia tăng, cũng xảy ra khi ứng dụng của bạn trước tiên cần truy cập vào các tài nguyên bổ sung 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 biết cách chuyển hướng người dùng tới URL uỷ quyền bằng web Flask khung ứng dụng:
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 = authorizer.get_authorization_url(login_hint: user_id, request: request)
- Chuyển hướng người dùng đến
auth_uri
.
Node.js
-
Sử dụng URL đã tạo
authorizationUrl
ở Bước 1 Phương thứcgenerateAuthUrl
để 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.redirect(authorizationUrl);
HTTP/REST
Mẫu chuyển hướng đến máy chủ uỷ quyền của Google
URL mẫu bên dưới yêu cầu quyền truy cập ngoại tuyến
(access_type=offline
) trong phạm vi cho phép truy xuất
các báo cáo trong YouTube Analytics của người dùng. Hàm này sử dụng uỷ quyền tăng dần để
đảm bảo rằng mã truy cập mới bao gồm mọi phạm vi mà người dùng
trước đây đã cấp quyền truy cập cho ứng dụng. URL cũng đặt giá trị cho thuộc tính
bắt buộc phải có redirect_uri
, response_type
và
tham số client_id
cũng như cho state
. URL chứa dấu ngắt dòng và dấu cách để dễ đọc.
https://accounts.google.com/o/oauth2/v2/auth?
scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyt-analytics.readonly&
access_type=offline&
include_granted_scopes=true&
state=state_parameter_passthrough_value&
redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback&
response_type=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 cho để truy cập vào các phạm vi được yêu cầu. Phản hồi sẽ được gửi lại ứng dụng của bạn bằng cách sử dụng URL chuyển hướng bạn đã chỉ định.
Bước 3: Google nhắc người dùng đồng ý
Ở bước này, người dùng sẽ quyết định xem có cấp cho ứng dụng của bạn quyền truy cập mà bạn yêu cầu hay không. Lúc này giai đoạn này, Google sẽ cho thấy một cửa sổ đồng ý cho thấy tên ứng dụng của bạn và Google API các dịch vụ mà nhà cung cấp đó đang yêu cầu cấp quyền truy cập bằng thông tin xác thực ủy quyền của người dùng và phần tóm tắt các phạm vi truy cập đã được cấp. Chiến lược phát hành đĩa đơn 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ì đang chờ phản hồi từ Máy chủ OAuth 2.0 của Google cho biết liệu có bất kỳ quyền truy cập nào được cấp hay không. Câu trả lời đó được giải thích bằng bước sau đây.
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. Các mã lỗi phổ biến và nội dung đề xuất được liệt kê dưới đây.
admin_policy_enforced
Tài khoản Google không thể cho phép một hoặc nhiều phạm vi đã yêu cầu do các chính sách của quản trị viên Google Workspace của họ. Xem bài viết trợ giúp dành cho Quản trị viên Google Workspace Kiểm soát bên thứ ba và các ứng dụng nội bộ truy cập vào dữ liệu trong Google Workspace để biết thêm thông tin về cách quản trị viên có thể hạn chế quyền truy cập vào tất cả các phạm vi hoặc các dữ liệu nhạy cảm và phạm vi bị hạn chế cho đến khi bạn cấp quyền truy cập rõ ràng cho mã ứng dụng khách OAuth.
disallowed_useragent
Điểm cuối uỷ quyền được hiển thị trong một tác nhân người dùng được nhúng bởi Chính sách của OAuth 2.0.
Android
Nhà phát triển Android có thể gặp phải 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ư
Tính năng Đăng nhập bằng Google dành cho Android hoặc tài khoản OpenID Foundation
AppAuth cho Android.
Các nhà phát triển web có thể gặp phải lỗi này khi ứng dụng Android mở một đường liên kết trang 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 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 của Google, bao gồm cả Đường liên kết trong ứng dụng Android hoặc ứng dụng trình duyệt mặc định. Chiến lược phát hành đĩa đơn Thẻ tuỳ chỉnh trong Android thư viện 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ở các 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ư
Tính năng Đăng nhập bằng Google cho iOS hoặc tài khoản OpenID Foundation
AppAuth cho iOS.
Các nhà phát triển web có thể gặp phải lỗi này khi một ứng dụng iOS hoặc macOS mở một đường liên kết trang web chung trong
tác nhân người dùng được nhúng và người dùng 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 của Google, bao gồm cả
Đường liên kết phổ quát
hoặc ứng dụng trình duyệt mặc định. Chiến lược phát hành đĩa đơn
SFSafariViewController
thư viện 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 một dự án giới hạn quyền truy cập vào Tài khoản Google trong một cụ thể Tổ chức Google Cloud. Để biết thêm thông tin về tuỳ chọn cấu hình này, hãy xem 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 OAuth không chính xác. Xem xét Ứng dụng OAuth cấu hình, bao gồm cả mã ứng dụng khách và khoá bí mật được 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 còn hiệu lực. Xác thực người dùng một lần nữa và yêu cầu người dùng đồng ý để lấy mã thông báo mới. Nếu bạn đang tiếp tục để xem lỗi này, hãy đảm bảo rằng ứng dụng của bạn đã được định cấu hình chính xác và bạn bằng cách sử dụng đúng mã thông báo và tham số trong yêu cầu của bạn. Nếu không, tài khoản người dùng có thể phải đã bị xóa hoặc vô hiệu hóa.
redirect_uri_mismatch
redirect_uri
đã chuyển trong yêu cầu uỷ quyền không khớp với với
chuyển hướng URI cho mã ứng dụng khách OAuth. Xem lại các URI chuyển hướng được uỷ quyền trong
Google API Console Credentials page.
Tham số redirect_uri
có thể tham chiếu đến luồng OAuth ngoài băng tần (OOB) đã
không được dùng nữa và không còn được hỗ trợ nữa. Tham khảo
hướng dẫn di chuyển để cập nhật
tích hợp.
invalid_request
Đã xảy ra lỗi với yêu cầu của bạn. Điều này có thể là do một số lý do:
- Yêu cầu không được định dạng đúng
- Yêu cầu thiếu thông số bắt buộc
- Yêu cầu này sử dụng một phương thức uỷ quyền mà Google không hỗ trợ. Xác minh OAuth của bạn sử dụng phương pháp tích hợp được đề xuất
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 phê duyệt 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 không phê duyệt yêu cầu, thì phản hồi có chứa thông báo lỗi. Chiến lược phát hành đĩa đơn mã uỷ quyền hoặc thông báo lỗi được trả về máy chủ web sẽ xuất hiện trên truy vấn như sau:
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 mẫu của máy chủ OAuth 2.0
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 truy cập chỉ đọ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%2F%2Fwww.googleapis.com%2Fauth%2Fyt-analytics.readonly& access_type=offline& include_granted_scopes=true& state=state_parameter_passthrough_value& redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback& response_type=code& client_id=client_id
Sau khi hoàn tất quy trình OAuth 2.0, bạn sẽ được chuyển hướng đến
http://localhost/oauth2callback
, có thể sẽ mang lại
404 NOT FOUND
trừ phi máy cục bộ của bạn phân phối tệp tại địa chỉ đó. Chiến lược phát hành đĩa đơn
bước tiếp theo cung cấp thêm chi tiết về thông tin được trả về trong URI khi người dùng
đã chuyển hướng quay 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 nhận được mã uỷ quyền, máy chủ web có thể trao đổi mã uỷ quyền đó cho một mã truy cập.
PHP
Để đổi mã uỷ quyền lấy mã truy cập, hãy sử dụng authenticate
phương thức:
$client->authenticate($_GET['code']);
Bạn có thể truy xuất mã 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 lệnh uỷ quyền
phản hồi của máy chủ. Sau đó, sử dụng phương thức flow.fetch_token
để trao đổi khoản tiền uỷ quyền này
trong phản hồi đó cho một 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/yt-analytics.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
Trên trang gọi lại, hãy sử dụng thư viện googleauth
để xác minh máy chủ uỷ quyền
của bạn. Sử dụng phương thức authorizer.handle_auth_callback_deferred
để lưu
mã uỷ quyền và chuyển hướng trở lại URL yêu cầu cấp quyền ban đầu. Chiến dịch này
trì hoãn việc trao đổi mã bằng cách tạm thời lưu trữ kết quả trong phiên của người dùng.
target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request) redirect target_url
Node.js
Để đổi mã uỷ quyền lấy mã truy cập, hãy sử dụng getToken
phương thức:
const url = require('url'); // Receive the callback from Google's OAuth 2.0 server. app.get('/oauth2callback', async (req, res) => { 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 if (q.state !== req.session.state) { //check state value console.log('State mismatch. Possible CSRF attack'); res.end('State mismatch. Possible CSRF attack'); } else { // Get access and refresh tokens (if access_type is offline) let { tokens } = await oauth2Client.getToken(q.code); oauth2Client.setCredentials(tokens); });
HTTP/REST
Để đổi mã uỷ quyền lấy mã truy cập, hãy gọi hàm
điểm cuối https://oauth2.googleapis.com/token
và đặt các tham số sau:
Trường | |
---|---|
client_id |
Mã ứng dụng khách lấy được từ API Console Credentials page |
client_secret |
Mật khẩu ứng dụng khách lấy được từ API Console Credentials page |
code |
Mã uỷ quyền được trả về từ yêu cầu ban đầu. |
grant_type |
Như được định nghĩa trong OAuth 2.0
chỉ số, thì giá trị của trường này phải được đặt thành authorization_code . |
redirect_uri |
Một trong những URI chuyển hướng được liệt kê cho dự án của bạn trong
API Console
Credentials page cho các giá trị cụ thể
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 có chứa quyền truy cập trong thời gian ngắn
và mã làm mới.
Lưu ý rằng mã làm mới chỉ được trả về nếu ứng dụng đặt giá trị access_type
cho offline
trong yêu cầu ban đầu đối với
máy chủ uỷ quyền.
Phản hồi có 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 để cho phép yêu cầu API của Google. |
expires_in |
Thời gian hoạt động 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ể dùng để lấy mã truy cập mới. Mã làm mới 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 giá trị access_type
với offline trong yêu cầu ban đầu gửi tới 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
chuỗi 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ề. Tại thời điểm 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/yt-analytics.readonly", "refresh_token": "1//xEoDL4iW3cxlI7yDbSRFYNG01kVKM2C-259HOF2aQbI" }
Lỗi
Khi trao đổi mã uỷ quyền lấy mã truy cập, bạn có thể gặp phải những sự cố sau thay vì phản hồi mong đợi. Các mã lỗi phổ biến và cách giải quyết được đề xuất là được liệt kê bên dưới.
invalid_grant
Mã uỷ quyền đã cung cấp không hợp lệ hoặc có định dạng sai. Yêu cầu mã mới chậm nhất vào bắt đầu lại quy trình OAuth để nhắc người dùng đồng ý một lần nữa.
Gọi API của Google
PHP
Sử dụng mã truy cập để gọi API của 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 vào đối tượng
Google\Client
mới – cho Ví dụ: nếu bạn lưu trữ mã truy cập trong một phiên 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 uỷ quyền cho hàm khởi tạo cho API mà bạn muốn gọi. Chẳng hạn, để gọi API YouTube Analytics, hãy làm như sau:$youtube = new Google_Service_YouTubeAnalytics($client);
- Gửi yêu cầu đến dịch vụ API bằng
giao diện do đối tượng dịch vụ cung cấp.
Ví dụ: để truy xuất báo cáo YouTube Analytics cho người dùng
kênh của người dùng:
$report = $youtube->reports->query('channel==MINE', '2016-05-01', '2016-06-30', 'views');
Python
Sau khi có mã truy cập, ứng dụng của bạn có thể dùng mã thông báo đó để cho phép yêu cầu API cho một tài khoản người dùng hoặc tài khoản dịch vụ cụ thể. Sử dụng thông tin xác thực uỷ 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 uỷ 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 phương thức tên và phiên bản của API và thông tin đăng nhập của người dùng: Chẳng hạn, cách gọi phiên bản 1 của API YouTube Analytics:from googleapiclient.discovery import build youtube = build('youtubeAnalytics', 'v1', credentials=credentials)
- Gửi yêu cầu đến dịch vụ API bằng
giao diện do đối tượng dịch vụ cung cấp.
Ví dụ: để truy xuất báo cáo YouTube Analytics cho người dùng
kênh của người dùng:
report = youtube.reports().query(ids='channel==MINE', start_date='2016-05-01', end_date='2016-06-30', metrics='views').execute()
Ruby
Sau khi có mã truy cập, ứng dụng của bạn có thể dùng mã thông báo đó để tạo yêu cầu API trên cho một tài khoản người dùng hoặc tài khoản dịch vụ cụ thể. Sử dụng thông tin xác thực uỷ 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 uỷ quyền.
- Tạo đối tượng dịch vụ cho API mà bạn muốn gọi.
Chẳng hạn, cách gọi phiên bản 1 của API YouTube Analytics:
youtube = Google::Apis::YoutubeAnalyticsV1::YouTubeAnalyticsService.new
- Đặt thông tin đăng nhập trên dịch vụ:
youtube.authorization = credentials
- Gửi yêu cầu đến dịch vụ API bằng
giao diện
do đối tượng dịch vụ cung cấp.
Ví dụ: để truy xuất báo cáo YouTube Analytics cho người dùng
kênh của người dùng:
report = youtube.query_report('channel==MINE', '2016-05-01', '2016-06-30', 'views')
Ngoài ra, việc uỷ quyền có thể được cung cấp theo từng phương thức bằng cách cung cấp
Tham số options
cho một phương thức:
report = youtube.query_report('channel==MINE', '2016-05-01', '2016-06-30', 'views', options: { authorization: auth_client })
Node.js
Sau khi lấy mã truy cập và đặt mã đó thành đối tượng OAuth2
, hãy sử dụng đối tượng này
để gọi Google API. Ứng dụng của bạn có thể dùng mã thông báo đó để cấp 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ụ cụ thể. 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
Sau khi ứng dụng của bạn nhận được mã truy cập, bạn có thể sử dụng mã này để thực hiện lệnh gọi đến Google
thay mặt cho một
tài khoản người dùng nếu(các) phạm vi quyền truy cập mà API yêu cầu đã được cấp. Để thực hiện việc này, hãy thêm
mã truy cập trong yêu cầu gửi đến API bằng cách bao gồm truy vấn access_token
hoặc một giá trị Bearer
của tiêu đề HTTP Authorization
. Nếu có thể,
nên ưu tiên sử dụng tiêu đề HTTP vì chuỗi truy vấn thường hiển thị trong nhật ký máy chủ. Trong hầu hết
bạn có thể sử dụng thư viện ứng dụng để thiết lập lệnh gọi đến các API của Google (ví dụ: khi
gọi API YouTube Analytics).
Xin lưu ý rằng YouTube Analytics API không hỗ trợ tài khoản dịch vụ luồng. API Báo cáo của YouTube chỉ hỗ trợ tài khoản dịch vụ cho Chủ sở hữu nội dung trên YouTube sở hữu và quản lý nhiều kênh YouTube, chẳng hạn như làm hãng thu âm và hãng phim.
Bạn có thể dùng thử tất cả API của Google và xem phạm vi của chúng ở Nền tảng OAuth 2.0.
Ví dụ về HTTP GET
Lệnh gọi đến
reports.query
điểm cuối (API YouTube Analytics) bằng HTTP Authorization: Bearer
có thể có dạng như sau. Xin lưu ý rằng bạn cần chỉ định mã truy cập của riêng mình:
GET /youtube/analytics/v1/reports?ids=channel%3D%3DMINE&start-date=2016-05-01&end-date=2016-06-30&metrics=views HTTP/1.1 Host: www.googleapis.com Authorization: Bearer access_token
Dưới đây là lệnh gọi đến cùng một API cho người dùng đã được xác thực bằng access_token
tham số chuỗi truy vấn:
GET https://www.googleapis.com/youtube/analytics/v1/reports?access_token=access_token&ids=channel%3D%3DMINE&start-date=2016-05-01&end-date=2016-06-30&metrics=views
Ví dụ về curl
Bạn có thể kiểm thử các lệnh này bằng ứng dụng dòng lệnh curl
. Sau đây là một
ví dụ sử dụng tuỳ chọn tiêu đề HTTP (ưu tiên):
curl -H "Authorization: Bearer access_token" https://www.googleapis.com/youtube/analytics/v1/reports?ids=channel%3D%3DMINE&start-date=2016-05-01&end-date=2016-06-30&metrics=views
Hoặc, một cách khác là tuỳ chọn tham số chuỗi truy vấn:
curl https://www.googleapis.com/youtube/analytics/v1/reports?access_token=access_token&ids=channel%3D%3DMINE&start-date=2016-05-01&end-date=2016-06-30&metrics=views
Ví dụ đầy đủ
Ví dụ sau đây in một đối tượng có định dạng JSON hiển thị dữ liệu về lượt xem cho kênh YouTube của người dùng đã xác thực đó, sau khi người dùng cấp quyền để truy xuất báo cáo trong YouTube Analytics.
PHP
Cách 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 một thư mục mới rồi đổi sang thư mục đó. Ví dụ:
mkdir ~/php-oauth2-example cd ~/php-oauth2-example
- Cài đặt Ứng dụng API của Google
Thư viện cho PHP sử dụng Composer:
composer require google/apiclient:^2.10
- Tạo các tệp
index.php
vàoauth2callback.php
có chứa nội dung bên dưới. - Chạy ví dụ với máy chủ web được định cấu hình để phân phát PHP. Nếu bạn sử dụng PHP 5.6 trở lên, bạn
có thể sử dụng máy chủ web kiểm tra được tích hợp sẵn 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_YouTubeAnalytics::YT_ANALYTICS_READONLY); if (isset($_SESSION['access_token']) && $_SESSION['access_token']) { $client->setAccessToken($_SESSION['access_token']); $youtube = new Google_Service_YouTubeAnalytics($client); $report = $youtube->reports->query('channel==MINE', '2016-05-01', '2016-06-30', 'views'); echo json_encode($report); } 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_YouTubeAnalytics::YT_ANALYTICS_READONLY); if (! isset($_GET['code'])) { // Generate and set state value $state = bin2hex(random_bytes(16)); $client->setState($state); $_SESSION['state'] = $state; $auth_url = $client->createAuthUrl(); header('Location: ' . filter_var($auth_url, FILTER_SANITIZE_URL)); } else { // Check the state value if (!isset($_GET['state']) || $_GET['state'] !== $_SESSION['state']) { die('State mismatch. Possible CSRF attack.'); } $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. Nó
chạy một ứng dụng web tại http://localhost:8080
cho phép bạn kiểm tra OAuth 2.0
luồng. Nếu truy cập vào URL đó, bạn sẽ thấy 4 đường liên kết:
- Kiểm thử yêu cầu API: Đường liên kết này trỏ đến một trang cố gắng thực thi API mẫu của bạn. Nếu cần, Google 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 thông qua quy trình uỷ quyền. Ứng dụng yêu cầu quyền để gửi các yêu cầu API được uỷ quyền thay mặt 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 đăng nhập phiên hoạt động trong Flask: Đường liên kết này sẽ xoá thông tin đăng nhập cấp phép được lưu trữ trong phiên Flask. Điều này cho phép bạn xem điều gì sẽ xảy ra nếu một người dùng đã được 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 thấy phản hồi của API mà ứng dụng của mình sẽ nhận được nếu người dùng đã thu hồi các quyền được cấp cho và ứng dụng của bạn vẫn cố gắng uỷ quyền cho một yêu cầu bằng mã 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/yt-analytics.readonly'] API_SERVICE_NAME = 'youtubeAnalytics' API_VERSION = 'v1' 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']) youtube = googleapiclient.discovery.build( API_SERVICE_NAME, API_VERSION, credentials=credentials) report = youtube.reports().query(ids='channel==MINE', start_date='2016-05-01', end_date='2016-06-30', metrics='views').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(**report) @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/youtube_analytics_v1' require 'sinatra' require 'googleauth' require 'googleauth/stores/redis_token_store' configure do enable :sessions set :client_id, Google::Auth::ClientId.from_file('/path/to/client_secret.json') set :scope, Google::Apis::DriveV3::AUTH_DRIVE_METADATA_READONLY set :token_store, Google::Auth::Stores::RedisTokenStore.new(redis: Redis.new) set :authorizer, Google::Auth::WebUserAuthorizer.new(settings.client_id, settings.scope, settings.token_store, '/oauth2callback') end get '/' do user_id = settings.client_id.id credentials = settings.authorizer.get_credentials(user_id, request) if credentials.nil? redirect settings.authorizer.get_authorization_url(login_hint: user_id, request: request) end youtube = Google::Apis::YoutubeAnalyticsV1::YouTubeAnalyticsService.new report = youtube.query_report('channel==MINE', '2016-05-01', '2016-06-30', 'views', options: { authorization: auth_client }) "<pre>#{JSON.pretty_generate(report.to_h)}</pre>" end get '/oauth2callback' do target_url = Google::Auth::WebUserAuthorizer.handle_auth_callback_deferred(request) redirect target_url end
Node.js
Cách 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ụ: hãy thêm
http://localhost
- Hãy đảm bảo rằng bạn có LTS bảo trì, LTS đang hoạt động hoặc bản phát hành hiện tại của Đã cài đặt Node.js.
-
Tạo một thư mục mới rồi đổi sang thư mục đó. Ví dụ:
mkdir ~/nodejs-oauth2-example cd ~/nodejs-oauth2-example
-
Cài đặt
Ứng dụng API của Google
Thư viện
cho Node.js bằng npm:
npm install googleapis
-
Tạo các tệp
main.js
với 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'); const crypto = require('crypto'); const express = require('express'); const session = require('express-session'); /** * 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' ]; /* 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 app = express(); app.use(session({ secret: 'your_secure_secret_key', // Replace with a strong secret resave: false, saveUninitialized: false, })); // Example on redirecting user to Google's OAuth 2.0 server. app.get('/', async (req, res) => { // Generate a secure random state value. const state = crypto.randomBytes(32).toString('hex'); // Store state in the session req.session.state = state; // 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, // Include the state parameter to reduce the risk of CSRF attacks. state: state }); res.redirect(authorizationUrl); }); // Receive the callback from Google's OAuth 2.0 server. app.get('/oauth2callback', async (req, res) => { // 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 if (q.state !== req.session.state) { //check state value console.log('State mismatch. Possible CSRF attack'); res.end('State mismatch. Possible CSRF attack'); } 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 app.get('/revoke', async (req, res) => { // 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(); }); const server = http.createServer(app); server.listen(80); } main().catch(console.error);
HTTP/REST
Ví dụ dùng đoạn mã Python này sử dụng khung Flask và thư viện Requests (Yêu cầu) để chứng minh OAuth Luồng web 2.0. Bạn nên sử dụng Thư viện ứng dụng API của Google dành cho Python cho quy trình này. (Các 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/yt-analytics.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/youtube/analytics/v1/reports' r = requests.get(req_uri, headers=headers) return r.text @app.route('/oauth2callback') def oauth2callback(): if 'code' not in flask.request.args: state = str(uuid.uuid4()) flask.session['state'] = state auth_uri = ('https://accounts.google.com/o/oauth2/v2/auth?response_type=code' '&client_id={}&redirect_uri={}&scope={}&state={}').format(CLIENT_ID, REDIRECT_URI, SCOPE, state) return flask.redirect(auth_uri) else: if 'state' not in flask.request.args or flask.request.args['state'] != flask.session['state']: return 'State mismatch. Possible CSRF attack.', 400 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()
Chuyển hướng quy tắc xác thực URI
Google áp dụng những quy tắc xác thực sau đây cho việc chuyển hướng URI để giúp nhà phát triển bảo mật các ứ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. Xem Mục 3 của RFC 3986 dành cho định nghĩa miền, máy chủ lưu trữ, đườ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 giao thức HTTPS, không phải là HTTP thuần tuý. URI của máy chủ cục bộ (bao gồm URI địa chỉ IP localhost) được miễn quy tắc này. |
Máy chủ lưu trữ |
Máy chủ không được là địa chỉ IP thô. Địa chỉ IP của máy chủ cục bộ được miễn tuân theo quy tắc này. |
Miền |
“googleusercontent.com” .goo.gl ), trừ phi
ứng dụng sở hữu miền. Hơn nữa, nếu một ứng dụng sở hữu miền rút ngắ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ụ thông tin người dùng. |
Đường dẫn |
URI chuyển hướng không được chứa một tính năng truyền tải qua đường dẫn (còn gọi là theo dõi ngược 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 mở lệnh chuyển hướng. |
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:
|
Uỷ quyền tăng dần
Trong giao thức OAuth 2.0, ứng dụng của bạn sẽ yêu cầu cấp quyền để truy cập vào các tài nguyên, tức là được xác định theo phạm vi. Đây được xem là phương pháp yêu cầu uỷ quyền mang lại trải nghiệm người dùng tốt nhất để có được các tài nguyên vào đúng thời điểm bạn cần. Để bật hoạt động đó, máy chủ uỷ quyền của Google hỗ trợ uỷ quyền gia tăng. 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ể là đã đổi lấy một mã thông báo chứa tất cả các phạm vi mà người dùng đã cấp cho dự án.
Ví dụ: giả sử một ứng dụng truy xuất các báo cáo trong YouTube Analytics, một số
là các báo cáo tiền tệ yêu cầu truy cập vào một phạm vi bổ sung không
cần thiết cho các báo cáo khác. Trong trường hợp này, tại thời điểm đăng nhập, ứng dụng chỉ có thể
yêu cầu quyền truy cập vào
Phạm vi https://www.googleapis.com/auth/yt-analytics.readonly
.
Tuy nhiên, nếu người dùng cố gắng truy xuất một báo cáo tiền tệ, ứng dụng cũng có thể
yêu cầu quyền truy cập vào
https://www.googleapis.com/auth/yt-analytics-monetary.readonly
phạm vi.
Để triển khai uỷ quyền tăng dần, bạn hãy hoàn tất quy trình thông thường để yêu cầu quyền truy cập mã thông báo nhưng hãy đảm bảo rằng yêu cầu uỷ quyền bao gồm các phạm vi đã cấp trước đó. Chiến dịch này giú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 áp dụng cho mã truy cập có được từ việc uỷ quyền tăng dần:
- 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 bất kỳ phạm vi nào được đưa vào uỷ quyền kết hợp mới.
- Khi bạn sử dụng mã làm mới cho hoạt động uỷ quyền kết hợp để lấy mã truy cập,
mã truy cập đại diện cho sự uỷ quyền kết hợp và có thể được dùng cho bất kỳ
scope
giá trị được đưa vào phản hồi. - Hoạt động uỷ quyền kết hợp bao gồm tất cả phạm vi mà người dùng đã cấp cho dự án API ngay cả khi nếu khoản tài trợ được yêu cầu từ các ứng dụng khác nhau. Ví dụ: nếu người dùng cấp quyền truy cập vào một phạm vi bằng cách sử dụng ứng dụng trên máy tính để bàn của một ứng dụng, sau đó cấp một phạm vi khác cho ứng dụng đó qua ứng dụng di động, 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ã thông báo đại diện cho một yêu cầu uỷ quyền kết hợp, thì bạn có thể truy cập vào tất cả những dữ liệu đó phạm vi uỷ quyền thay mặt cho người dùng được liên kết được thu hồi đồng thời.
Mã mẫu theo ngôn ngữ cụ thể trong Bước 1: Thiết lập chế độ uỷ quyền tham số và URL chuyển hướng HTTP/REST mẫu trong Bước 2: Tất cả các lượt 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 hiển thị mã mà bạn cần phải thêm để sử dụ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
thành
đảm bảo rằng yêu cầu uỷ quyền 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ừ khoá duy nhất mà bạn đặt, vì
như 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')
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
Trong ví dụ này, ứng dụng gọi yêu cầu quyền truy cập để truy xuất dữ liệu YouTube Analytics của người dùng cùng với bất kỳ quyền truy cập nào khác mà người dùng đó đã cấp cho ứng dụng.
GET https://accounts.google.com/o/oauth2/v2/auth? scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyt-analytics.readonly& access_type=offline& state=security_token%3D138rk%3Btarget_url%3Dhttp...index& redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback& response_type=code& client_id=client_id& include_granted_scopes=true
Refreshing an access token (offline access)
Access tokens periodically expire and become invalid credentials for a related API request. You can refresh an access token without prompting the user for permission (including when the user is not present) if you requested offline access to the scopes associated with the token.
- If you use a Google API Client Library, the client object refreshes the access token as needed as long as you configure that object for offline access.
- If you are not using a client library, you need to set the
access_type
HTTP query parameter tooffline
when redirecting the user to Google's OAuth 2.0 server. In that case, Google's authorization server returns a refresh token when you exchange an authorization code for an access token. Then, if the access token expires (or at any other time), you can use a refresh token to obtain a new access token.
Requesting offline access is a requirement for any application that needs to access a Google
API when the user is not present. For example, an app that performs backup services or
executes actions at predetermined times needs to be able to refresh its access token when the
user is not present. The default style of access is called online
.
Server-side web applications, installed applications, and devices all obtain refresh tokens during the authorization process. Refresh tokens are not typically used in client-side (JavaScript) web applications.
PHP
If your application needs offline access to a Google API, set the API client's access type to
offline
:
$client->setAccessType("offline");
Sau khi người dùng cấp quyền truy cập ngoại tuyến vào phạm vi đã yêu cầu, bạn có thể tiếp tục sử dụng API để truy cập API của Google thay mặt người dùng khi người dùng đang ngoại tuyến. Đối tượng ứng dụng sẽ làm mới mã truy cập nếu cần.
Python
Trong Python, hãy đặt đối số từ khoá access_type
thành offline
để đảm bảo
bạn sẽ có thể làm mới mã truy cập mà không cần phải nhắc lại người dùng
quyền. Rất có thể access_type
sẽ không phải là từ khóa duy nhất
mà bạn đặt, như 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 phạm vi đã yêu cầu, bạn có thể tiếp tục sử dụng API để truy cập API của Google thay mặt người dùng khi người dùng đang ngoại tuyến. Đối tượng ứng dụng 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 ngoại tuyến vào Google API, 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 phạm vi đã yêu cầu, bạn có thể tiếp tục sử dụng API để truy cập API của Google thay mặt người dùng khi người dùng đang ngoại tuyến. Đối tượng ứng dụng 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 ngoại tuyến vào Google API, 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 phạm vi đã yêu cầu, bạn có thể tiếp tục sử dụng API để truy cập API của Google thay mặt người dùng khi người dùng đang ngoại tuyến. Đối tượng ứng dụng sẽ làm mới mã truy cập nếu cần.
Mã truy cập sẽ hết hạn. Thư viện này sẽ tự động dùng mã làm mới để có được quyền truy cập mới mã thông báo 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ỉ xảy ra trong lần uỷ quyền đầu tiên và bạn cần phải đặt
access_type
đến offline
khi gọi generateAuthUrl
để nhận mã làm mới. Nếu bạn đã cấp cho ứng dụng các quyền cần thiết
nếu không đặt ra những ràng buộc thích hợp để nhận mã làm mới, bạn sẽ cần
ủy quyền lại ứng dụng để nhận mã làm mới mới.
Để đặt refresh_token
vào lúc khác, 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ẽ được thu nạp và làm mới tự động trong lệnh gọi API tiếp theo.
HTTP/REST
Để làm mới mã truy cập, ứng dụng của bạn sẽ gửi một POST
HTTPS
yêu cầu máy chủ uỷ quyền của Google (https://oauth2.googleapis.com/token
)
bao gồm các thông số sau:
Trường | |
---|---|
client_id |
Mã ứng dụng khách lấy được từ API Console. |
client_secret |
Mật khẩu ứng dụng khách lấy được từ API Console. |
grant_type |
Như
được xác định trong
Quy cách 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ừ quá trình 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ề một đối tượng JSON chứa mã thông báo truy cập mới. Đoạn mã sau đây cho thấy một mẫu trả lời:
{ "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 mỗi khách hàng/người dùng và một tổ hợp khách hàng/người dùng khác cho mỗi người dùng trên tất cả khách hàng. Bạn nên lưu mã làm mới trong bộ nhớ dài hạn và tiếp tục sử dụng miễn là 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ì mã này có thể gặp phải các giới hạn này. Trong trường hợp đó, các mã 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ấ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 Account Settings (Cài đặt tài khoản). Xem Xoá phần truy cập trang web hoặc ứng dụng trong mục Trang web bên thứ ba & các ứng dụng 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 cách lập trình. Việc thu hồi có lập trình là rất quan trọng trong trường hợp người dùng huỷ đăng ký, xoá ứng dụng hoặ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, Một phần của quy trình xoá có thể bao gồm yêu cầu API để đảm bảo các quyền trước đó được cấp cho ứng dụng sẽ 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 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 tham số và đặt giá trị
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 oauth2.revoke
điểm cuối:
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 đó là một 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 việc 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
đượ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 gửi yêu cầu POST qua HTTPS tới /revoke
điểm cuối:
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 đó là một 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 việc 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
được trả về cùng với
mã lỗi.
HTTP/REST
Để thu hồi mã thông báo theo cách lập trình, ứng dụng sẽ đưa ra yêu cầu
https://oauth2.googleapis.com/revoke
và bao gồm mã thông báo dưới dạng tham 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ã thông báo là một 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 việc 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
có mã lỗi.
Triển khai tính năng Bảo vệ nhiều tài khoản
Bạn nên thực hiện thêm một bước để bảo vệ đang triển khai tính năng Nhiều tài khoản Bảo vệ bằng cách sử dụng Dịch vụ bảo vệ nhiều tài khoản của Google. Dịch vụ này cho phép bạn đăng ký nhận thông báo sự kiện bảo mật nhằm cung cấp thông tin cho ứng dụng của bạn về những thay đổi lớn đối với tài khoản người dùng. Sau đó, bạn có thể sử dụng thông tin này để thực hiện hành động tùy thuộc vào cách bạn quyết định phản hồi sự kiện.
Dưới đây là một số ví dụ về các loại sự kiện mà Dịch vụ bảo vệ nhiều tài khoản của Google gửi tới ứng dụng của bạn:
-
https://schemas.openid.net/secevent/risc/event-type/sessions-revoked
-
https://schemas.openid.net/secevent/oauth/event-type/token-revoked
-
https://schemas.openid.net/secevent/risc/event-type/account-disabled
Xem Bảo vệ tài khoản người dùng bằng trang Bảo vệ nhiều tài khoản để biết thêm thông tin về cách triển khai tính năng Bảo vệ nhiều tài khoản và để biết danh sách đầy đủ các sự kiện hiện có.