OAuth 2.0:透過 Google 驗證使用者

OAuth2 是業界標準的授權通訊協定。這個 API 提供的機制可讓使用者在不分享使用者名稱、密碼和其他私人憑證的情況下,授予網頁和電腦版應用程式存取私人資訊的權限。

本教學課程建構一項擴充功能,以便使用 Google People APIChrome Identity API 存取使用者的 Google 聯絡人。由於擴充功能不會透過 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. 在開發人員資訊主頁中,按一下「新增商品」
  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 與開發人員資訊主頁中的項目 ID。兩者應一致。

與擴充功能的 ID 相符

建立 OAuth 用戶端 ID

前往 Google API 控制台,然後建立新專案。準備就緒後,選取側欄中的「Credentials」,按一下「Create credentials」並選擇「OAuth client ID」

為擴充功能建立憑證

在「Create client ID」(建立用戶端 ID) 頁面上,選取「Chrome Extension」(Chrome 擴充功能)。填寫擴充功能名稱,並將擴充功能 ID 置於「應用程式 ID」欄位的網址結尾。

填寫擴充功能資訊

按一下「建立」即可完成。控制台會提供 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);
    });
  });
};

index.html 的標頭中加入 oauth.js 的指令碼標記。

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

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

在控制台中查看權杖

啟用 Google People API

返回 Google API 控制台,然後選取側欄中的「程式庫」。搜尋「Google People API」,然後按一下正確的結果並啟用該 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 金鑰。擴充功能應記錄 memberResourceNames 欄位下方含有 people/account_id 陣列的 JSON 物件。

封鎖臉孔

擴充功能現在會傳回使用者聯絡人清單,因此可以提出其他要求來擷取這些聯絡人的設定檔與資訊。擴充功能會使用 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);
                  });
            };
          });
    });
  });
};

重新載入並返回擴充功能。按一下 [FriendBlock] 按鈕,立刻一探究竟!在某個街區

封鎖對象的臉孔