使用 OAuth 2.0 處理 JavaScript 網頁應用程式

本文說明如何執行 OAuth 2.0 授權以存取 移除 JavaScript 網頁應用程式的 YouTube Data APIOAuth 2.0 可讓使用者 與應用程式分享特定資料,同時保留使用者名稱、密碼和其他 私人資訊。 舉例來說,應用程式可以使用 OAuth 2.0 取得權限 將影片上傳到使用者的 YouTube 頻道。

這個 OAuth 2.0 流程稱為「隱含授權流程」。這項設計專為 應用程式只有在使用者處於使用狀態時,才能存取 API。這些 應用程式無法儲存機密資訊。

在本流程中,您的應用程式會開啟 Google 網址,透過查詢參數來識別您的應用程式 以及應用程式所需的 API 存取權類型你可以在目前的瀏覽器中開啟網址 視窗或彈出式視窗使用者可以透過 Google 進行驗證並授予要求的權限。 接著 Google 會將使用者重新導向回您的應用程式。重新導向中包含存取權杖, 驗證您的應用程式,並使用這項工具提出 API 要求。

Google API 用戶端程式庫和 Google Identity 服務

如果您使用 JavaScript 適用的 Google API 用戶端程式庫 若要對 Google 進行授權呼叫,則應使用 Google Identity 服務 JavaScript 程式庫,用於處理 OAuth 2.0 流程。詳情請參閱 Google 身分識別服務符記模型, 計算依據:OAuth 2.0 隱含授權流程。

必要條件

為專案啟用 API

凡是呼叫 Google API 的應用程式,都必須在 API Console。

如何在專案中啟用 API:

  1. Open the API Library 內 Google API Console。
  2. If prompted, select a project, or create a new one.
  3. 在「資料庫」頁面中,找出並啟用 YouTube Data API。尋找其他 您的應用程式將使用並啟用這些 API。

建立授權憑證

凡是使用 OAuth 2.0 存取 Google API 的應用程式,都必須具備授權憑證 可與 Google 的 OAuth 2.0 伺服器識別應用程式。下列步驟說明如何 為專案建立憑證接著,您的應用程式即可使用憑證存取 API 找出您已啟用的專案

  1. Go to the Credentials page.
  2. 按一下 [Create credentials] (建立憑證) > [OAuth client ID] (OAuth 用戶端 ID)
  3. 選取「網頁應用程式」應用程式類型。
  4. 填妥表單。使用 JavaScript 提出授權 Google API 要求的應用程式 必須指定已授權的 JavaScript 來源。來源可用來辨識來自 您的應用程式可以將請求傳送至 OAuth 2.0 伺服器。這些來源必須遵循 Google 的驗證規則

識別存取權範圍

限定範圍可讓應用程式只要求存取其所需資源, 讓使用者控制他們授予應用程式的存取權限量。因此, 可能是要求的範圍數量與 徵得使用者同意

建議您先確定執行 OAuth 2.0 授權的範圍後,再開始執行 OAuth 2.0 授權 才能存取您的應用程式

YouTube Data API 第 3 版使用下列範圍:

狙擊鏡
https://www.googleapis.com/auth/youtube管理您的 YouTube 帳戶
https://www.googleapis.com/auth/youtube.channel-memberships.creator查看您現有的有效頻道會員清單,以及這些會員目前的級別和成為會員的時間點
https://www.googleapis.com/auth/youtube.force-ssl查看、編輯並永久刪除您的 YouTube 影片、評分、留言和字幕
https://www.googleapis.com/auth/youtube.readonly查看您的 YouTube 帳戶
https://www.googleapis.com/auth/youtube.upload管理您的 YouTube 影片
https://www.googleapis.com/auth/youtubepartner查看及管理您在 YouTube 上的元素和相關內容
https://www.googleapis.com/auth/youtubepartner-channel-audit查看您的 YouTube 頻道中與 YouTube 合作夥伴稽核程序相關的私人資訊

OAuth 2.0 API 範圍文件提供了 列出可能用於存取 Google API 的範圍清單。

取得 OAuth 2.0 存取權杖

下列步驟顯示應用程式如何與 Google 的 OAuth 2.0 伺服器互動,以取得 使用者同意代為執行 API 要求。您的應用程式必須符合下列條件 才能執行需要使用者授權的 Google API 要求。

步驟 1:重新導向至 Google 的 OAuth 2.0 伺服器

如需要求存取使用者資料的權限,請將使用者重新導向至 Google 的 OAuth 2.0 伺服器

OAuth 2.0 端點

產生網址,透過位於 的 Google OAuth 2.0 端點要求存取權 https://accounts.google.com/o/oauth2/v2/auth。這個端點可透過 HTTPS 存取; 系統會拒絕透過原定的 HTTP 連線,

Google 授權伺服器支援下列適用於網站的查詢字串參數: 伺服器應用程式:

參數
client_id 必填

應用程式的用戶端 ID。您可以在 API Console Credentials page

redirect_uri 必填

決定 API 伺服器在使用者完成提示後,將他們重新導向何處 授權流程。這個值必須與其中一個已授權的重新導向 URI 完全相符 OAuth 2.0 用戶端,也就是您在用戶端的 API Console Credentials page。如果這個值與 提供的 client_id 授權重新導向 URI redirect_uri_mismatch 個錯誤。

請注意,httphttps 配置、大小寫和結尾斜線 (「/」) 必須全部相符。

response_type 必填

JavaScript 應用程式必須將參數值設為 token。這個 值會指示 Google 授權伺服器將存取權杖做為 name=value 會在 URI (#) 的片段 ID 中配對 使用者完成授權程序後,系統就會將使用者重新導向。

scope 必填

A 罩杯 以空格分隔 這些範圍清單會指出應用程式可在 代表使用者這些值決定 Google 向 內容。

限定範圍可讓應用程式只要求存取其所需資源 並讓使用者控制授予 應用程式。因此,要求的範圍數量之間存在反向關係 以及取得使用者同意聲明的可能性

YouTube Data API 第 3 版使用下列範圍:

狙擊鏡
https://www.googleapis.com/auth/youtube管理您的 YouTube 帳戶
https://www.googleapis.com/auth/youtube.channel-memberships.creator查看您現有的有效頻道會員清單,以及這些會員目前的級別和成為會員的時間點
https://www.googleapis.com/auth/youtube.force-ssl查看、編輯並永久刪除您的 YouTube 影片、評分、留言和字幕
https://www.googleapis.com/auth/youtube.readonly查看您的 YouTube 帳戶
https://www.googleapis.com/auth/youtube.upload管理您的 YouTube 影片
https://www.googleapis.com/auth/youtubepartner查看及管理您在 YouTube 上的元素和相關內容
https://www.googleapis.com/auth/youtubepartner-channel-audit查看您的 YouTube 頻道中與 YouTube 合作夥伴稽核程序相關的私人資訊

OAuth 2.0 API 範圍文件提供了 包含可用於存取 Google API 的完整範圍清單。

建議您讓應用程式要求授權範圍的存取權 。透過以下方式,要求存取使用者資料: 漸進式授權,可讓使用者更輕鬆地 瞭解應用程式為何需要其要求的存取權。

state 建議事項

指定應用程式用來維持 授權要求和授權伺服器的回應。 伺服器會傳回您以 name=value 組合形式傳送的確切值, 網址片段 ID (#) 的 redirect_uri使用者同意或拒絕應用程式的 存取要求。

這個參數可用於多種用途,例如將使用者導向 在應用程式中使用正確的資源、傳送 Nonce 以及降低跨網站要求 偽造。由於您可以猜測 redirect_uri,因此使用 state 值可讓您確保傳入連線的結果是 驗證要求如果您產生隨機字串或將 Cookie 雜湊編碼 另一個會擷取用戶端狀態的值,您可以驗證 也要確保請求和回應都來自相同的瀏覽器。 提供網路攻擊防護功能 跨網站要求 偽造。詳情請參閱 OpenID Connect 範例,說明如何建立並確認 state 權杖。

include_granted_scopes 選用

允許應用程式使用漸進式授權,要求存取其他 定義範圍如果您將這個參數的值設為 true,且 獲得授權要求後,新的存取權杖也涵蓋將 也就是使用者先前授予應用程式存取權的使用者。詳情請參閱 漸進式授權一節。

login_hint 選用

如果應用程式知道哪個使用者想要進行驗證,則可以使用此參數 為 Google 驗證伺服器提供提示伺服器會利用提示 透過在登入表單中預先填入電子郵件欄位,或 選取適當的多帳戶登入工作階段

將參數值設為電子郵件地址或 sub ID ( 會對應至使用者的 Google ID

prompt 選用

以空格分隔且區分大小寫的提示清單,用於向使用者顯示。如果您不 指定這個參數,系統只會提示使用者第一次執行專案 要求存取權。詳情請參閱 提示重新提供同意聲明以瞭解詳情。

可能的值為:

none 不要顯示任何驗證或同意畫面。不得使用 其他值。
consent 提示使用者表示同意。
select_account 提示使用者選取帳戶。

重新導向至 Google 授權伺服器的範例

下方範例網址要求離線存取 將 access_type=offline 設為可查看存取權的範圍 使用者的 YouTube 帳戶。它使用漸進式授權 新的存取權杖涵蓋使用者先前授予的所有範圍 應用程式存取權該網址同時設定了必要的值 redirect_uriresponse_typeclient_idstate 參數。網址含有換行符號和方便閱讀的空格。

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.readonly&
 include_granted_scopes=true&
 state=state_parameter_passthrough_value&
 redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback&
 response_type=token&
 client_id=client_id

建立要求網址之後,請將使用者重新導向至該網址。

JavaScript 程式碼範例

下列 JavaScript 程式碼片段說明如何在 不使用 JavaScript 的 Google API 用戶端程式庫。自這個 OAuth 存取以來 2.0 端點不支援跨源資源共享 (CORS),程式碼片段會建立 表單,開啟要求傳送至該端點。

/*
 * Create form to request access token from Google's OAuth 2.0 server.
 */
function oauthSignIn() {
  // Google's OAuth 2.0 endpoint for requesting an access token
  var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

  // Create <form> element to submit parameters to OAuth 2.0 endpoint.
  var form = document.createElement('form');
  form.setAttribute('method', 'GET'); // Send as a GET request.
  form.setAttribute('action', oauth2Endpoint);

  // Parameters to pass to OAuth 2.0 endpoint.
  var params = {'client_id': 'YOUR_CLIENT_ID',
                'redirect_uri': 'YOUR_REDIRECT_URI',
                'response_type': 'token',
                'scope': 'https://www.googleapis.com/auth/youtube.force-ssl',
                'include_granted_scopes': 'true',
                'state': 'pass-through value'};

  // Add form parameters as hidden input values.
  for (var p in params) {
    var input = document.createElement('input');
    input.setAttribute('type', 'hidden');
    input.setAttribute('name', p);
    input.setAttribute('value', params[p]);
    form.appendChild(input);
  }

  // Add form to page and submit it to open the OAuth 2.0 endpoint.
  document.body.appendChild(form);
  form.submit();
}

步驟 2:Google 會提示使用者同意

在這個步驟中,使用者決定是否授予應用程式要求的存取權。在此 Google 會顯示同意聲明視窗,顯示您的應用程式名稱和 Google API 服務要求權限,才能存取使用者的授權憑證 存取權範圍摘要 使用者就能選擇同意授權,存取一或多個應用程式要求的範圍。 拒絕要求。

應用程式會等待以下期間的回應,因此在這個階段無須採取任何行動 Google 的 OAuth 2.0 伺服器會指出是否已獲得任何存取權。詳細說明請參閱 請按照下列步驟進行。

錯誤

向 Google 的 OAuth 2.0 授權端點發出的要求可能會顯示針對使用者顯示的錯誤訊息 而非預期的驗證與授權流程常見的錯誤代碼和建議事項 解析度列於下方。

admin_policy_enforced

根據下列政策,Google 帳戶無法授權一或多個要求的範圍 Google Workspace 管理員參閱 Google Workspace 管理員說明文章 控管哪些第三方和內部應用程式存取 Google Workspace 資料 進一步瞭解管理員可能如何限制所有範圍或敏感資料的存取權,以及 受到限制,直到已明確授予 OAuth 用戶端 ID 存取權為止。

disallowed_useragent

授權端點會顯示在 Google 的 OAuth 2.0 政策

Android

Android 開發人員在 android.webkit.WebView。 開發人員應改用 Android 程式庫,例如 Android 版 Google 登入或 OpenID Foundation 的 AppAuth for Android

當 Android 應用程式在 內嵌使用者代理程式,而使用者前往 Google 的 OAuth 2.0 授權端點 你的網站開發人員應允許使用預設連結處理常式開啟一般連結, 其中包括 Android 應用程式連結 處理常式或預設的瀏覽器應用程式中。 Android 自訂分頁 另一個支援選項

iOS

iOS 和 macOS 開發人員在 WKWebView。 開發人員應改用 iOS 程式庫,例如 iOS 版 Google 登入或 OpenID Foundation 的 AppAuth for iOS

當 iOS 或 macOS 應用程式在 內嵌使用者代理程式,然後使用者透過 你的網站開發人員應允許使用預設連結處理常式開啟一般連結, 其中包括 通用連結 處理常式或預設的瀏覽器應用程式中。 SFSafariViewController敬上 另一個支援選項

org_internal

請求中的 OAuth 用戶端 ID 所屬的專案,限制了 Google 帳戶存取 特定 Google Cloud 機構。 如要進一步瞭解這個設定選項,請參閱 使用者類型 部分。

invalid_client

提出要求的來源並未獲得該用戶端的授權。詳情請見 origin_mismatch

invalid_grant

使用漸進式授權時,權杖可能已過期 或已失效 再次驗證使用者,並要求使用者同意取得新的權杖。如果您選擇繼續 看到這則錯誤訊息,請確認您的應用程式設定正確, 要求使用正確的符記和參數否則,使用者帳戶 可能已遭刪除或停用

origin_mismatch

產生授權要求的 JavaScript 配置、網域和/或通訊埠 與為 OAuth 用戶端 ID 註冊的已授權 JavaScript 來源 URI 相符。已授權審查 Google API Console中的 JavaScript 來源 Credentials page

redirect_uri_mismatch

授權要求中傳遞的 redirect_uri 與已授權要求不符 OAuth 用戶端 ID 的重新導向 URI。查看 Google API Console Credentials page

產生授權要求的 JavaScript 配置、網域和/或通訊埠 與為 OAuth 用戶端 ID 註冊的已授權 JavaScript 來源 URI 相符。檢閱 已授權的 JavaScript 來源 Google API Console Credentials page

redirect_uri 參數可能是指 OAuth 的架構外 (OOB) 流程, 已淘汰,不再受到支援。詳情請參閱 遷移指南,以更新 擷取及準備資料、針對特定領域進行預先訓練 調整指示、離線評估和整合

invalid_request

您提出的要求發生問題。可能原因如下:

  • 要求的格式不正確
  • 要求中缺少必要參數
  • 這項要求使用了 Google 不支援的授權方法。驗證 OAuth 整合採用建議的整合方式

步驟 3:處理 OAuth 2.0 伺服器回應

OAuth 2.0 端點

OAuth 2.0 伺服器會將回應傳送至您在redirect_uri 存取權杖

如果使用者核准要求,回應就會提供存取權杖。如果使用者 未核准要求,回應會包含錯誤訊息。存取權杖 錯誤訊息會在重新導向 URI 的雜湊片段上傳回,如下所示:

  • 存取權杖回應:

    https://oauth2.example.com/callback#access_token=4/P7q7W91&token_type=Bearer&expires_in=3600

    除了 access_token 參數外,片段字串也會 包含 token_type 參數,該參數一律會設為 Bearerexpires_in 參數,用來指定 憑證的生命週期 (以秒為單位)。如果已指定 state 參數 ,其值也會納入回應中。

  • 錯誤回應:
    https://oauth2.example.com/callback#error=access_denied
,瞭解如何調查及移除這項存取權。

OAuth 2.0 伺服器回應範例

如要測試這個流程,請點選下列範例網址 可透過唯讀權限查看 Google 雲端硬碟檔案的中繼資料:

https://accounts.google.com/o/oauth2/v2/auth?
 scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fyoutube.readonly&
 include_granted_scopes=true&
 state=state_parameter_passthrough_value&
 redirect_uri=http%3A%2F%2Flocalhost%2Foauth2callback&
 response_type=token&
 client_id=client_id

完成 OAuth 2.0 流程後,系統會將您重新導向至 http://localhost/oauth2callback。網址就會產生 404 NOT FOUND 錯誤,除非本機機器於以下位置提供檔案: 該網址下一步將進一步說明 使用者重新導向回應用程式時的 URI。

呼叫 Google API

OAuth 2.0 端點

應用程式取得存取權杖後,您可以使用該權杖向 Google 代表指定的 使用者帳戶。方法是加入 加入 access_token 查詢,藉此將存取權杖用於傳送至 API 的要求中 參數或 Authorization HTTP 標頭 Bearer 值。可能的話 HTTP 標頭較為理想,因為這類字串通常會顯示在伺服器記錄中。大多數 使用用戶端程式庫來設定對 Google API 的呼叫 (例如,在 呼叫 YouTube Data API)。

請注意,YouTube Data API 僅支援 YouTube 服務帳戶 擁有並管理多個 YouTube 頻道的內容擁有者,例如錄製內容 像是唱片公司和電影公司

您可以試用所有 Google API 並查看相關範圍: OAuth 2.0 Playground

HTTP GET 範例

youtube.channels 端點 (YouTube Data API) Authorization: BearerHTTP 標題可能如下所示。請注意,您必須指定自己的存取權杖:

GET /youtube/v3/channels?part=snippet&mine=true HTTP/1.1
Host: www.googleapis.com
Authorization: Bearer access_token

下方的呼叫是使用 access_token 為通過驗證的使用者呼叫相同的 API。 查詢字串參數:

GET https://www.googleapis.com/youtube/v3/channels?access_token=access_token&part=snippet&mine=true

curl 範例

您可以使用 curl 指令列應用程式測試這些指令。以下是 使用 HTTP 標頭選項的範例 (建議):

curl -H "Authorization: Bearer access_token" https://www.googleapis.com/youtube/v3/channels?part=snippet&mine=true

或者,您也可以使用查詢字串參數選項:

curl https://www.googleapis.com/youtube/v3/channels?access_token=access_token&part=snippet&mine=true

JavaScript 程式碼範例

以下程式碼片段示範如何使用 CORS (跨源資源共享) 將 Google API 要求。這個範例未使用 JavaScript 的 Google API 用戶端程式庫, 不過,就算您不使用用戶端程式庫, 該程式庫說明文件中的 CORS 支援指南也許能協助您解決問題 以便進一步瞭解這些要求

在這個程式碼片段中,access_token 變數代表您擁有的符記 。完整 範例,示範如何在瀏覽器的本機儲存空間儲存並擷取該權杖 提出 API 請求

var xhr = new XMLHttpRequest();
xhr.open('GET',
    'https://www.googleapis.com/youtube/v3/channels?part=snippet&mine=true&' +
    'access_token=' + params['access_token']);
xhr.onreadystatechange = function (e) {
  console.log(xhr.response);
};
xhr.send(null);

完整範例

OAuth 2.0 端點

這個程式碼範例將示範如何在不使用 Google API JavaScript 的用戶端程式庫。這段程式碼是 HTML 網頁,這些網頁會顯示 嘗試提出 API 要求如果您點選按鈕,程式碼就會檢查網頁是否儲存 瀏覽器本機儲存空間中的 API 存取權杖。如果相符,就會執行 API 要求。否則 就會啟動 OAuth 2.0 流程

如果是 OAuth 2.0 流程,頁面會顯示下列步驟:

  1. 系統會將使用者導向至 Google 的 OAuth 2.0 伺服器, https://www.googleapis.com/auth/youtube.force-ssl 範圍。
  2. 授予 (或拒絕) 存取一或多個要求範圍的存取權後,系統會將使用者重新導向至 原始網頁,剖析片段 ID 字串中的存取權杖。
  3. 這個網頁會使用存取權杖發出範例 API 要求。

    這個 API 要求會呼叫 YouTube Data API 的 channels.list 方法 擷取授權使用者 YouTube 頻道的相關資料。

  4. 如果要求成功執行,API 回應會記錄在瀏覽器的偵錯中 控制台。

若要撤銷應用程式的存取權,請使用 「權限」頁面 Google 帳戶。系統會將該應用程式列為 Google API 文件的 OAuth 2.0 示範版本

如要在本機執行此程式碼,您需要設定 YOUR_CLIENT_IDYOUR_REDIRECT_URI相應變數 授權憑證YOUR_REDIRECT_URI 變數 必須設為放送網頁的網址。值必須完全符合其中一個 OAuth 2.0 用戶端的授權重新導向 URI (您在 API Console Credentials page。如果 這個值與授權的 URI 不符,您會收到 redirect_uri_mismatch 錯誤。您的專案必須同時採用 為這項要求啟用適當的 API

<html><head></head><body>
<script>
  var YOUR_CLIENT_ID = 'REPLACE_THIS_VALUE';
  var YOUR_REDIRECT_URI = 'REPLACE_THIS_VALUE';

  // Parse query string to see if page request is coming from OAuth 2.0 server.
  var fragmentString = location.hash.substring(1);
  var params = {};
  var regex = /([^&=]+)=([^&]*)/g, m;
  while (m = regex.exec(fragmentString)) {
    params[decodeURIComponent(m[1])] = decodeURIComponent(m[2]);
  }
  if (Object.keys(params).length > 0 && params['state']) {
    if (params['state'] == localStorage.getItem('state')) {
      localStorage.setItem('oauth2-test-params', JSON.stringify(params) );

      trySampleRequest();
    } else {
      console.log('State mismatch. Possible CSRF attack');
    }
  }

  // Function to generate a random state value
  function generateCryptoRandomState() {
    const randomValues = new Uint32Array(2);
    window.crypto.getRandomValues(randomValues);

    // Encode as UTF-8
    const utf8Encoder = new TextEncoder();
    const utf8Array = utf8Encoder.encode(
      String.fromCharCode.apply(null, randomValues)
    );

    // Base64 encode the UTF-8 data
    return btoa(String.fromCharCode.apply(null, utf8Array))
      .replace(/\+/g, '-')
      .replace(/\//g, '_')
      .replace(/=+$/, '');
  }

  // If there's an access token, try an API request.
  // Otherwise, start OAuth 2.0 flow.
  function trySampleRequest() {
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    if (params && params['access_token']) {
      var xhr = new XMLHttpRequest();
      xhr.open('GET',
          'https://www.googleapis.com/youtube/v3/channels?part=snippet&mine=true&' +
          'access_token=' + params['access_token']);
      xhr.onreadystatechange = function (e) {
        if (xhr.readyState === 4 && xhr.status === 200) {
          console.log(xhr.response);
        } else if (xhr.readyState === 4 && xhr.status === 401) {
          // Token invalid, so prompt for user permission.
          oauth2SignIn();
        }
      };
      xhr.send(null);
    } else {
      oauth2SignIn();
    }
  }

  /*
   * Create form to request access token from Google's OAuth 2.0 server.
   */
  function oauth2SignIn() {
    // create random state value and store in local storage
    var state = generateCryptoRandomState();
    localStorage.setItem('state', state);

    // Google's OAuth 2.0 endpoint for requesting an access token
    var oauth2Endpoint = 'https://accounts.google.com/o/oauth2/v2/auth';

    // Create element to open OAuth 2.0 endpoint in new window.
    var form = document.createElement('form');
    form.setAttribute('method', 'GET'); // Send as a GET request.
    form.setAttribute('action', oauth2Endpoint);

    // Parameters to pass to OAuth 2.0 endpoint.
    var params = {'client_id': YOUR_CLIENT_ID,
                  'redirect_uri': YOUR_REDIRECT_URI,
                  'scope': 'https://www.googleapis.com/auth/youtube.force-ssl',
                  'state': state,
                  'include_granted_scopes': 'true',
                  'response_type': 'token'};

    // Add form parameters as hidden input values.
    for (var p in params) {
      var input = document.createElement('input');
      input.setAttribute('type', 'hidden');
      input.setAttribute('name', p);
      input.setAttribute('value', params[p]);
      form.appendChild(input);
    }

    // Add form to page and submit it to open the OAuth 2.0 endpoint.
    document.body.appendChild(form);
    form.submit();
  }
</script>

<button onclick="trySampleRequest();">Try sample request</button>
</body></html>

JavaScript 來源驗證規則

Google 會將下列驗證規則套用至 JavaScript 來源,以協助 可確保應用程式安全無虞您的 JavaScript 來源必須遵守這些規則。 請參閱 RFC 3986 第 3 節,瞭解 定義了網域、主機和配置。

驗證規則
配置

JavaScript 來源必須使用 HTTPS 通訊協定,而非純文字 HTTP。本機主機 URI (包括 localhost IP 位址 URI) 不受這項規則影響。

主機

主機不得為原始 IP 位址。本機主機 IP 位址不在這項規則範圍內。

網域
  • 主機 TLD (頂層網域) 必須隸屬於公開尾碼清單
  • 主機網域不得為 “googleusercontent.com”
  • JavaScript 來源不能包含網址縮短網域 (例如 goo.gl) 除非應用程式擁有網域
  • 使用者資訊

    JavaScript 來源不可包含 userinfo 子元件。

    路徑

    JavaScript 來源不能包含路徑元件。

    查詢

    JavaScript 來源不能包含查詢元件。

    Fragment

    JavaScript 來源不能包含片段元件。

    字元 JavaScript 來源不得包含特定字元,包括:
    • 萬用字元字元 ('*')
    • 不可列印的 ASCII 字元
    • 百分比編碼無效 (任何未遵循網址編碼的百分比編碼) 的值格式為百分比,後面加上兩個十六進位數字)
    • 空值字元 (編碼的 NULL 字元,例如%00, %C0%80)

    漸進式授權

    在 OAuth 2.0 通訊協定中,應用程式要求存取資源, 依範圍識別要求授權是最佳的使用者體驗 隨時查看所需資源為了進行這項練習,Google 的授權伺服器 支援漸進式授權這項功能可讓您在需要時要求範圍 如果使用者授予新範圍的權限,則會傳回可能是 用來交換的憑證,該憑證包含使用者已授予專案的所有範圍。

    舉例來說,假設有一款應用程式能協助使用者辨識值得注意的當地活動。 這個應用程式可讓使用者觀看活動相關影片、為影片評分,以及新增 影片加入播放清單使用者也可以使用應用程式將活動新增到 Google 日曆。

    在此情況下,應用程式可能在登入時不需要或要求存取 不受任何範圍限制不過,如果使用者嘗試給予影片評分,則請將影片新增至 播放清單,或執行其他 YouTube 動作,該應用程式可能會要求存取 https://www.googleapis.com/auth/youtube.force-ssl 範圍。 同樣地,應用程式可以要求存取 https://www.googleapis.com/auth/calendar 範圍 (如果使用者嘗試執行這項操作) 新增日曆活動。

    下列規則適用於從漸進式授權取得的存取權杖:

    • 無論資料是隸屬於哪個範圍,都能用來存取相應的資源。 新的合併授權。
    • 當您使用更新權杖取得合併授權以取得存取權杖時, 存取權杖代表了合併授權,可用於任何 回應中包含 scope 個值。
    • 合併授權包括使用者授予 API 專案的所有範圍 則來自不同用戶端的要求舉例來說,如果使用者 一個範圍,然後使用應用程式的桌面用戶端,然後將另一個範圍授予相同的 行動用戶端簽署應用程式時,合併授權將包括這兩個範圍。
    • 如果撤銷代表合併授權的權杖, 同時撤銷關聯使用者的授權範圍。
    ,瞭解如何調查及移除這項存取權。

    下列程式碼範例說明如何將範圍新增至現有的存取權杖。這個方法 ,省去管理多個存取權杖的麻煩。

    OAuth 2.0 端點

    在此範例中,呼叫的應用程式要求存取 使用者的 YouTube 數據分析資料 。

    如要將範圍新增至現有存取權杖,請加入 include_granted_scopes 參數加到Google 的 OAuth 2.0 伺服器要求中。

    下列程式碼片段說明如何執行這項作業。程式碼片段假設您已儲存 瀏覽器本機儲存空間中您的存取權杖有效的範圍。( complete example 程式碼會儲存存取符記的範圍清單 在瀏覽器的本機上設定 oauth2-test-params.scope 屬性,才有效 storage.)

    程式碼片段會比較存取權杖有效的範圍和您要使用的範圍 特定查詢的結果如果存取權杖未涵蓋該範圍,OAuth 2.0 流程就會啟動。 此處的 oauth2SignIn 函式與 步驟 2 (將於之後的 )。

    var SCOPE = 'https://www.googleapis.com/auth/youtube.force-ssl';
    var params = JSON.parse(localStorage.getItem('oauth2-test-params'));
    
    var current_scope_granted = false;
    if (params.hasOwnProperty('scope')) {
      var scopes = params['scope'].split(' ');
      for (var s = 0; s < scopes.length; s++) {
        if (SCOPE == scopes[s]) {
          current_scope_granted = true;
        }
      }
    }
    
    if (!current_scope_granted) {
      oauth2SignIn(); // This function is defined elsewhere in this document.
    } else {
      // Since you already have access, you can proceed with the API request.
    }

    撤銷權杖

    在某些情況下,使用者可能會希望撤銷應用程式的存取權。使用者可以撤銷存取權 請造訪 帳戶設定。詳情請參閱 移除 網站或應用程式存取權部分具有您帳戶存取權的應用程式 支援文件。

    應用程式也可能會透過程式撤銷授予的存取權。 如果使用者取消訂閱、移除 應用程式所需的 API 資源,或應用程式所需的 API 資源大幅變更。也就是 移除程序中的某個部分可包含 API 要求,確保先前取得的權限 授予應用程式的權限就會遭到移除

    OAuth 2.0 端點

    如要透過程式撤銷權杖,應用程式會向 https://oauth2.googleapis.com/revoke,並將權杖做為參數加入:

    curl -d -X -POST --header "Content-type:application/x-www-form-urlencoded" \
            https://oauth2.googleapis.com/revoke?token={token}

    可以是存取權杖或更新權杖。如果權杖是存取權杖,且 對應的更新權杖也會撤銷更新權杖。

    如果撤銷成功處理完畢,回應的 HTTP 狀態碼 200。如果是錯誤狀況,系統會一併傳回 HTTP 狀態碼 400 傳回。

    下列 JavaScript 程式碼片段說明如何在不使用 Google API JavaScript 的用戶端程式庫。因為 Google 的 OAuth 2.0 端點撤銷 權杖不支援跨源資源共享 (CORS),程式碼會建立表單並提交 傳送表單到端點,而不要使用 XMLHttpRequest() 方法張貼 請求。

    function revokeAccess(accessToken) {
      // Google's OAuth 2.0 endpoint for revoking access tokens.
      var revokeTokenEndpoint = 'https://oauth2.googleapis.com/revoke';
    
      // Create <form> element to use to POST data to the OAuth 2.0 endpoint.
      var form = document.createElement('form');
      form.setAttribute('method', 'post');
      form.setAttribute('action', revokeTokenEndpoint);
    
      // Add access token to the form so it is set as value of 'token' parameter.
      // This corresponds to the sample curl request, where the URL is:
      //      https://oauth2.googleapis.com/revoke?token={token}
      var tokenField = document.createElement('input');
      tokenField.setAttribute('type', 'hidden');
      tokenField.setAttribute('name', 'token');
      tokenField.setAttribute('value', accessToken);
      form.appendChild(tokenField);
    
      // Add form to page and submit it to actually revoke the token.
      document.body.appendChild(form);
      form.submit();
    }

    導入跨帳戶防護功能

    您應採取的其他步驟來保護使用者帳戶導入跨帳戶 採用 Google 的跨帳戶防護服務,確保帳戶安全無虞。這項服務可讓您 訂閱安全性事件通知,為您的應用程式提供 使用者帳戶的重大變更然後根據這些資料採取行動 您決定如何回應事件

    以下列舉幾種 Google 跨帳戶防護服務傳送到您應用程式的事件類型:

    • 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

    詳情請參閱 透過跨帳戶防護頁面保護使用者帳戶 ,進一步瞭解如何導入跨帳戶防護功能,以及查看可用事件的完整清單。