google.accounts.oauth2
JavaScript 程式庫可協助您向使用者索取同意聲明,並取得存取權方代碼,以便處理使用者資料。這個 API 以 OAuth 2.0 隱含授權流程為基礎,可讓您使用 REST 和 CORS 直接呼叫 Google API,或是使用 JavaScript 適用的 Google API 用戶端程式庫 (也稱為 gapi.client
),以簡單靈活的方式存取更複雜的 API。
在使用者透過瀏覽器存取受保護的使用者資料前,網站上的使用者會觸發 Google 的網路帳戶選擇器、登入和同意程序,最後,Google 的 OAuth 伺服器會向您的網路應用程式發出及傳回存取權杖。
在權杖式授權模式中,您不需要在後端伺服器上儲存個別使用者的重新整理權杖。
建議您遵循本文所述方法,而非採用舊版 用於用戶端網頁應用程式的 OAuth 2.0 指南所述的技術。
設定
請按照「取得 Google API 用戶端 ID」指南中的步驟找出或建立用戶端 ID。接下來,請將用戶端程式庫新增至網站上將呼叫 Google API 的頁面。最後,初始化權杖用戶端。這項作業通常會在用戶端程式庫的 onload
處理常式中完成。
初始化權杖用戶端
請呼叫 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()
方法觸發權杖使用者體驗流程,並取得存取權杖。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()
時持續保留。根據預設,使用者首次造訪網站並要求新的範圍時,才需要使用者同意,但在每個網頁載入時,您也可以使用 Token 客戶端設定物件中的 prompt=consent
要求同意聲明。
使用符記
在權杖模型中,OS 或瀏覽器不會儲存存取權杖,而是會在網頁載入時取得新權杖,或透過使用者手勢 (例如按下按鈕) 觸發對 requestAccessToken()
的呼叫。
搭配 Google API 使用 REST 和 CORS
存取權杖可用於透過 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 程式庫
權杖用戶端程式可與 JavaScript 專用 Google API 用戶端程式庫搭配使用。請參閱下方的程式碼片段。
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);
});