使用符記模型

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 都會觸發使用者同意時機,您的應用程式將只能存取使用者選擇展開的部分所需的資源,藉此透過使用者選擇限制資源共用。

多個網頁

設計增量授權功能時,請使用多個網頁,只要求載入網頁所需的範圍,藉此減少複雜性,並避免需要多次呼叫來取得使用者同意聲明,以及擷取存取權權杖。

多頁面應用程式
網頁 程式碼
第 1 頁。閱讀說明文件
  const client = google.accounts.oauth2.initTokenClient({
    client_id: 'YOUR_GOOGLE_CLIENT_ID',
    callback: "onTokenResponse",
    scope: 'https://www.googleapis.com/auth/documents.readonly',
  });
  client.requestAccessToken();
          
第 2 頁。近期活動
  const client = google.accounts.oauth2.initTokenClient({
    client_id: 'YOUR_GOOGLE_CLIENT_ID',
    callback: "onTokenResponse",
    scope: 'https://www.googleapis.com/auth/calendar.readonly',
  });
  client.requestAccessToken();
          
第 3 頁。相片輪轉介面
  const client = google.accounts.oauth2.initTokenClient({
    client_id: 'YOUR_GOOGLE_CLIENT_ID',
    callback: "onTokenResponse",
    scope: 'https://www.googleapis.com/auth/photoslibrary.readonly',
  });
  client.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);
  });