OAuth 2.0:透過 Google 驗證使用者

OAuth2 是業界標準的授權通訊協定,使用者可透過這個機制 授予網路和桌面應用程式存取私人資訊,而不分享使用者名稱。 和其他私人憑證

本教學課程會建置一種擴充功能,以透過 Google People 功能存取使用者的 Google 聯絡人 APIChrome Identity API。因為擴充功能 HTTPS,就無法執行 重新導向或設定 Cookie,必須透過 Chrome Identity API 使用 OAuth2。

開始使用

請先建立目錄和下列範例程式碼檔案。

manifest.json

建立名為 manifest.json 的檔案來新增資訊清單,並加入下列程式碼。

{
  "name": "OAuth Tutorial FriendBlock",
  "version": "1.0",
  "description": "Uses OAuth to connect to Google's People API and display contacts photos.",
  "manifest_version": 3,
  "action": {
    "default_title": "FriendBlock, friends face's in a block."
  },
  "background": {
    "service_worker": "service-worker.js"
  }
}

service-worker.js

建立名為 service-worker.js 的檔案,並加入下列程式碼,即可新增擴充功能 Service Worker。

chrome.action.onClicked.addListener(function() {
  chrome.tabs.create({url: 'index.html'});
});

index.html

新增名為 index.html 的 HTML 檔案,並加入以下程式碼。

<html>
  <head>
    <title>FriendBlock</title>
    <style>
      button {
        padding: 10px;
        background-color: #3C79F8;
        display: inline-block;
      }
    </style>
  </head>
  <body>
    <button>FriendBlock Contacts</button>
    <div id="friendDiv"></div>
  </body>
</html>

使用一致的擴充功能 ID

在開發期間,請務必保留單一 ID。請按照下列步驟維持 ID 的一致性:

將擴充功能上傳至開發人員資訊主頁

將擴充功能目錄封裝到 .zip 檔案中,並上傳至 Chrome 開發人員 資訊主頁而不發布:

  1. 在開發人員資訊主頁中,按一下「Add new item」
  2. 按一下「瀏覽檔案」,選取擴充功能的 ZIP 檔案並上傳。
  3. 前往「套件」分頁,然後點選「查看公開金鑰」

開發人員資訊主頁套件分頁

開啟彈出式視窗後,請按照下列步驟操作:

  1. 請複製 -----BEGIN PUBLIC KEY----------END PUBLIC KEY----- 之間的程式碼。
  2. 移除換行符號,讓該行文字變成單行文字。

公開金鑰彈出式視窗

將程式碼新增至 "key" 欄位下方的 manifest.json。 這樣擴充功能就會使用相同的 ID。

{ // manifest.json
  "manifest_version": 3,
...
  "key": "ThisKeyIsGoingToBeVeryLong/go8GGC2u3UD9WI3MkmBgyiDPP2OreImEQhPvwpliioUMJmERZK3zPAx72z8MDvGp7Fx7ZlzuZpL4yyp4zXBI+MUhFGoqEh32oYnm4qkS4JpjWva5Ktn4YpAWxd4pSCVs8I4MZms20+yx5OlnlmWQEwQiiIwPPwG1e1jRw0Ak5duPpE3uysVGZXkGhC5FyOFM+oVXwc1kMqrrKnQiMJ3lgh59LjkX4z1cDNX3MomyUMJ+I+DaWC2VdHggB74BNANSd+zkPQeNKg3o7FetlDJya1bk8ofdNBARxHFMBtMXu/ONfCT3Q2kCY9gZDRktmNRiHG/1cXhkIcN1RWrbsCkwIDAQAB",
}

比較 ID

chrome://extensions 中開啟「擴充功能管理」頁面,確認已啟用「開發人員模式」。 並上傳未封裝的擴充功能目錄比較擴充功能管理上的擴充功能 ID 頁面。兩者必須一致。

SDK 的 ID
額外資訊比對

建立 OAuth 用戶端 ID

前往 Google API 控制台,建立新專案。準備就緒後,請選取 在側欄中「憑證」,按一下「建立憑證」,然後選擇「OAuth 用戶端 ID」

建立擴充功能憑證

在「Create client ID」(建立用戶端 ID) 頁面中,選取「Chrome Extension」(Chrome 擴充功能)。填寫額外資訊的名稱和位置 。

填寫擴充功能資訊

點選「建立」即可完成設定控制台會提供 OAuth 用戶端 ID,

在資訊清單中註冊 OAuth

在擴充功能資訊清單中加入 "oauth2" 欄位。請將產生的 OAuth 用戶端 ID 放在 "client_id"。暫時在 "scopes" 中加入空白字串。

{
  "name": "OAuth Tutorial FriendBlock",
  ...
  "oauth2": {
    "client_id": "yourExtensionOAuthClientIDWillGoHere.apps.googleusercontent.com",
    "scopes":[""]
  },
  ...
}

啟動第一個 OAuth 流程

在資訊清單中註冊 identity 權限。

{
  "name": "OAuth Tutorial FriendBlock",
  ...
  "permissions": [
    "identity"
  ],
  ...
}

建立檔案來管理名為 oauth.js 的 OAuth 流程,並加入下列程式碼。

window.onload = function() {
  document.querySelector('button').addEventListener('click', function() {
    chrome.identity.getAuthToken({interactive: true}, function(token) {
      console.log(token);
    });
  });
};

oauth.js 的指令碼標記放在 index.html 的標頭之中。

...
  <head>
    <title>FriendBlock</title>
    ...
    <script type="text/javascript" src="oauth.js"></script>
  </head>
...

重新載入擴充功能,然後按一下瀏覽器圖示,即可開啟 index.html。開啟控制台,按一下「FriendBlock 聯絡人」按鈕。控制台會顯示 OAuth 權杖。

在控制台中查看權杖

啟用 Google People API

返回 Google API 控制台,然後從側欄選取「Library」。搜尋「Google 使用者」 API」之後,按一下正確的結果並加以啟用。

啟用 People API

Google People API 用戶端程式庫,新增至擴充功能資訊清單的 "scopes"

{
  "name": "OAuth Tutorial FriendBlock",
  ...
  "oauth2": {
    "client_id": "yourExtensionOAuthClientIDWillGoHere.apps.googleusercontent.com",
    "scopes": [
      "https://www.googleapis.com/auth/contacts.readonly"
    ]
  },
  ...
}

返回 Google API 控制台,然後返回「憑證」。按一下「建立憑證」和 選取「API 金鑰」。

建立 People API 憑證

保留產生的 API 金鑰供日後使用。

建立第一個 API 要求

現在擴充功能具備適當權限和憑證,並能授權 Google 使用者 透過 People API 要求資料。請更新 oauth.js 中的程式碼,使其如下所示。

window.onload = function() {
  document.querySelector('button').addEventListener('click', function() {
    chrome.identity.getAuthToken({interactive: true}, function(token) {
      let init = {
        method: 'GET',
        async: true,
        headers: {
          Authorization: 'Bearer ' + token,
          'Content-Type': 'application/json'
        },
        'contentType': 'json'
      };
      fetch(
          'https://people.googleapis.com/v1/contactGroups/all?maxMembers=20&key=API_KEY',
          init)
          .then((response) => response.json())
          .then(function(data) {
            console.log(data)
          });
    });
  });
};

API_KEY 替換成 Google API 控制台產生的 API 金鑰。擴充功能 應記錄 JSON 物件,其中含有 people/account_id 陣列的 「memberResourceNames」欄位中的值。

封鎖臉孔

擴充功能現在會傳回使用者的聯絡人清單,現在可以發出其他要求 擷取這些聯絡人的個人資料和資訊。擴充功能會使用 memberResourceNames 可擷取使用者聯絡人的相片資訊。將 oauth.js 更新為 加入下列程式碼

window.onload = function() {
  document.querySelector('button').addEventListener('click', function() {
    chrome.identity.getAuthToken({interactive: true}, function(token) {
      let init = {
        method: 'GET',
        async: true,
        headers: {
          Authorization: 'Bearer ' + token,
          'Content-Type': 'application/json'
        },
        'contentType': 'json'
      };
      fetch(
          'https://people.googleapis.com/v1/contactGroups/all?maxMembers=20&key=<API_Key_Here>',
          init)
          .then((response) => response.json())
          .then(function(data) {
            let photoDiv = document.querySelector('#friendDiv');
            let returnedContacts = data.memberResourceNames;
            for (let i = 0; i < returnedContacts.length; i++) {
              fetch(
                  'https://people.googleapis.com/v1/' + returnedContacts[i] +
                      '?personFields=photos&key=API_KEY',
                  init)
                  .then((response) => response.json())
                  .then(function(data) {
                    let profileImg = document.createElement('img');
                    profileImg.src = data.photos[0].url;
                    photoDiv.appendChild(profileImg);
                  });
            };
          });
    });
  });
};

重新載入並返回擴充功能。按一下 [FriendsBlock] 按鈕,然後查看!CANNOT TRANSLATE 建立區塊

區塊中的聯絡人臉孔