OAuth 2.0:向 Google 验证用户身份

OAuth2 是业界标准的授权协议。它提供了一种机制,可让用户向 Web 应用和桌面应用授予对私密信息的访问权限,而无需共享其用户名、密码和其他私密凭据。

本教程介绍了如何使用 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. 转到 Package 标签页,然后点击 View public key

开发者信息中心的“软件包”标签页

打开弹出式窗口后,请按以下步骤操作:

  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 控制台并创建一个新项目。准备就绪后,在边栏中选择凭据,点击创建凭据并选择 OAuth 客户端 ID

为扩展程序创建凭据

在“创建客户端 ID”页面上,选择 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 Contacts”按钮。OAuth 令牌将显示在控制台中。

在控制台中查看令牌

启用 Google People API

返回 Google API 控制台,然后从边栏中选择。搜索“Google People 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 对象,其中在 memberResourceNames 字段下包含一组 people/account_id

屏蔽面孔

现在,该扩展程序正在返回用户的联系人列表,接下来可以发出其他请求来检索这些联系人的个人资料和信息。该扩展程序将使用 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 按钮在区块中欣赏联系人的面孔。

街区中的联系人面孔