google.accounts.oauth2
JavaScript 程式庫可協助您提示使用者同意,並取得存取權杖來處理使用者資料。這項服務以 OAuth 2.0 隱含授權流程為基礎,可讓您直接使用 REST 和 CORS 呼叫 Google API,也可以使用 JavaScript 適用的 Google API 用戶端程式庫 (也稱為 gapi.client
),輕鬆彈性地存取較複雜的 API。
從瀏覽器存取受保護的使用者資料前,網站上的使用者會觸發 Google 的網頁版帳戶選擇器、登入和同意程序,最後 Google 的 OAuth 伺服器會核發存取權杖,並傳回給您的網路應用程式。
在權杖式授權模型中,您不需要在後端伺服器上儲存每個使用者的重新整理權杖。
建議您採用本文所述方法,而非舊版「針對用戶端網頁應用程式使用 OAuth 2.0」指南涵蓋的技術。
必要條件
按照「設定」一節所述步驟,設定 OAuth 同意畫面、取得用戶端 ID,並載入用戶端程式庫。
初始化權杖用戶端
呼叫 initTokenClient()
,使用網頁應用程式的用戶端 ID 初始化新的權杖用戶端,您需要加入使用者需要存取的一或多個範圍清單:
const client = google.accounts.oauth2.initTokenClient({
client_id: 'YOUR_GOOGLE_CLIENT_ID',
scope: 'https://www.googleapis.com/auth/calendar.readonly',
callback: (response) => {
...
},
});
觸發 OAuth 2.0 權杖流程
使用 requestAccessToken()
方法觸發權杖 UX 流程,並取得存取權杖。Google 會提示使用者:
- 選擇帳戶,
- 登入 Google 帳戶 (若當下尚未登入),
- 同意網頁應用程式存取每個要求的範圍。
使用者手勢會觸發權杖流程:<button onclick="client.requestAccessToken();">Authorize me</button>
接著,Google 會將 TokenResponse
(內含存取權權杖和使用者已授予存取權的範圍清單) 或錯誤傳回給回呼處理常式。
使用者可能會關閉帳戶選擇器或登入視窗,在這種情況下,系統不會叫用回呼函式。
如何處理同意聲明
請詳閱 Google 的 OAuth 2.0 政策,再實作應用程式的設計和使用者體驗。這些政策涵蓋使用多個範圍、何時及如何處理使用者同意聲明等主題。
增量授權是一種政策和應用程式設計方法,可讓您只在需要時使用範圍要求資源存取權,而不是預先一次要求所有權限。使用者可以核准或拒絕分享應用程式要求的個別資源,這稱為「細部權限」。
在這個過程中,Google 會提示使用者同意授權,並逐一列出要求的範圍,使用者選取要與應用程式共用的資源後,Google 會呼叫您的回呼函式,傳回存取權杖和使用者核准的範圍。接著,應用程式會安全地處理細部權限可能造成的各種不同結果。
但也有例外情況。如果 Google Workspace Enterprise 應用程式具有網域範圍的授權委派,或是標示為「可信任」,系統就會略過詳細權限同意畫面。對於這類應用程式,使用者不會看到適當的權限同意畫面。應用程式會收到所有要求的範圍,或完全沒有。
如需更多詳細資訊,請參閱「如何處理精細權限」。
增量授權
如果是網路應用程式,以下兩個高階情境會示範如何使用下列項目進行增量授權:
- 單頁 Ajax 應用程式,通常會使用
XMLHttpRequest
動態存取資源。 - 多個網頁,資源會依網頁分隔和管理。
這兩個情境僅用來說明設計考量和方法,並非在應用程式中導入同意聲明的完整建議。實際應用程式可能會使用這些技術的變化或組合。
Ajax
多次呼叫 requestAccessToken()
並使用 OverridableTokenClientConfig
物件的 scope
參數,在需要時才要求個別範圍,且僅在必要時才要求,即可在應用程式中新增增量授權支援。在這個範例中,只有在使用者手勢展開已收合的內容區段後,才會要求並顯示資源。
Ajax 應用程式 |
---|
在網頁載入時初始化權杖用戶端:
const client = google.accounts.oauth2.initTokenClient({ client_id: 'YOUR_GOOGLE_CLIENT_ID', callback: "onTokenResponse", }); 待閱讀的文件顯示最近的文件 client.requestAccessToken( overrideConfig = ({ scope = 'https://www.googleapis.com/auth/documents.readonly' }) ); 近期活動顯示日曆資訊 client.requestAccessToken( overrideConfig = ({ scope = 'https://www.googleapis.com/auth/calendar.readonly' }) ); 相片輪轉介面顯示相片 client.requestAccessToken( overrideConfig = ({ scope = 'https://www.googleapis.com/auth/photoslibrary.readonly' }) ); |
每次呼叫 requestAccessToken
時,系統都會觸發使用者同意程序,應用程式只會存取使用者選擇展開的區段所需資源,因此可透過使用者選擇限制資源共用。
多個網頁
設計遞增授權時,系統會使用多個頁面,只要求載入頁面所需的範圍,減少複雜度,並避免多次呼叫以取得使用者同意聲明及擷取存取權杖。
多頁應用程式 | ||||||||
---|---|---|---|---|---|---|---|---|
|
每個頁面都會要求必要的範圍,並在載入時呼叫 initTokenClient()
和 requestAccessToken()
,取得存取權杖。在這種情況下,個別網頁會依範圍清楚區分使用者功能和資源。在實際情況中,個別網頁可能會要求多個相關範圍。
精細權限
在所有情境中,系統都會以相同方式處理精細權限;requestAccessToken()
叫用回呼函式並傳回存取權杖後,請使用 hasGrantedAllScopes()
或 hasGrantedAnyScope()
檢查使用者是否已核准要求的範圍。例如:
const client = google.accounts.oauth2.initTokenClient({
client_id: 'YOUR_GOOGLE_CLIENT_ID',
scope: 'https://www.googleapis.com/auth/calendar.readonly \
https://www.googleapis.com/auth/documents.readonly \
https://www.googleapis.com/auth/photoslibrary.readonly',
callback: (tokenResponse) => {
if (tokenResponse && tokenResponse.access_token) {
if (google.accounts.oauth2.hasGrantedAnyScope(tokenResponse,
'https://www.googleapis.com/auth/photoslibrary.readonly')) {
// Look at pictures
...
}
if (google.accounts.oauth2.hasGrantedAllScopes(tokenResponse,
'https://www.googleapis.com/auth/calendar.readonly',
'https://www.googleapis.com/auth/documents.readonly')) {
// Meeting planning and review documents
...
}
}
},
});
先前工作階段或要求中已接受的任何授權,也會納入回應。系統會為每位使用者和每個用戶端 ID 維護使用者同意聲明記錄,並在多次呼叫 initTokenClient()
或 requestAccessToken()
時保留這些記錄。根據預設,使用者只需要在首次造訪網站並要求新範圍時提供同意聲明,但您可以使用權杖用戶端設定物件中的 prompt=consent
,在每次載入網頁時要求同意聲明。
使用權杖
在權杖模型中,作業系統或瀏覽器不會儲存存取權杖,而是在網頁載入時首次取得新權杖,或是在使用者手勢 (例如按下按鈕) 觸發對 requestAccessToken()
的呼叫時取得新權杖。
搭配使用 REST 和 CORS 與 Google API
存取權杖可用於透過 REST 和 CORS,向 Google API 發出已驗證的要求。這樣一來,使用者就能登入、授予同意聲明,Google 也能核發存取權杖,您的網站則可使用使用者資料。
在本範例中,使用 tokenRequest()
傳回的存取權權杖,查看已登入使用者即將進行的日曆活動:
var xhr = new XMLHttpRequest();
xhr.open('GET', 'https://www.googleapis.com/calendar/v3/calendars/primary/events');
xhr.setRequestHeader('Authorization', 'Bearer ' + tokenResponse.access_token);
xhr.send();
詳情請參閱「如何使用 CORS 存取 Google API」。
下一節將說明如何輕鬆整合更複雜的 API。
使用 Google API JavaScript 程式庫
權杖用戶端可與 Google API JavaScript 專用用戶端程式庫搭配使用。請參閱下方的程式碼片段。
const client = google.accounts.oauth2.initTokenClient({
client_id: 'YOUR_GOOGLE_CLIENT_ID',
scope: 'https://www.googleapis.com/auth/calendar.readonly',
callback: (tokenResponse) => {
if (tokenResponse && tokenResponse.access_token) {
gapi.client.setApiKey('YOUR_API_KEY');
gapi.client.load('calendar', 'v3', listUpcomingEvents);
}
},
});
function listUpcomingEvents() {
gapi.client.calendar.events.list(...);
}
權杖到期
根據設計,存取權杖的生命週期很短。如果存取權杖在使用者工作階段結束前過期,請透過使用者觸發的事件 (例如按下按鈕) 呼叫 requestAccessToken()
,取得新權杖。
使用存取權杖撤銷同意聲明
呼叫 google.accounts.oauth2.revoke
方法,移除使用者同意聲明,並撤銷應用程式在所有已授權範圍內存取資源的權限。您必須使用有效的存取權杖撤銷這項權限:
google.accounts.oauth2.revoke('414a76cb127a7ece7ee4bf287602ca2b56f8fcbf7fcecc2cd4e0509268120bd7', done => {
console.log(done);
console.log(done.successful);
console.log(done.error);
console.log(done.error_description);
});