OAuth 2.0: xác thực người dùng với Google

OAuth2 là giao thức tiêu chuẩn ngành để ủy quyền. Chính sách này cung cấp cơ chế để người dùng cấp cho các ứng dụng web và máy tính quyền truy cập vào thông tin riêng tư mà không cần chia sẻ tên người dùng, mật khẩu và thông tin đăng nhập riêng tư khác của họ.

Hướng dẫn này sẽ tạo một tiện ích để truy cập vào danh bạ Google của người dùng bằng Google People APIChrome Identity API. Vì không thể tải qua HTTPS, không thể thực hiện chuyển hướng hoặc đặt cookie, nên các tiện ích này dựa vào API Chrome Identity để sử dụng OAuth2.

Bắt đầu

Bắt đầu bằng cách tạo thư mục và các tệp khởi đầu sau.

manifest.json

Thêm tệp kê khai bằng cách tạo một tệp có tên manifest.json và đưa vào đoạn mã sau.

{
  "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

Thêm worker dịch vụ tiện ích bằng cách tạo một tệp có tên service-worker.js và thêm đoạn mã sau vào.

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

index.html

Thêm một tệp HTML có tên là index.html và đưa vào đoạn mã sau.

<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>

Giữ một mã tiện ích nhất quán

Việc duy trì một mã nhận dạng là cần thiết trong quá trình phát triển. Để giữ mã nhận dạng nhất quán, hãy làm theo các bước sau:

Tải tiện ích lên trang tổng quan dành cho nhà phát triển

Đóng gói thư mục tiện ích vào một tệp .zip rồi tải tệp đó lên Trang tổng quan dành cho nhà phát triển Chrome mà không cần phát hành tệp này:

  1. Trên Trang tổng quan dành cho nhà phát triển, hãy nhấp vào Thêm mặt hàng mới.
  2. Nhấp vào Duyệt tệp, chọn tệp zip của tiện ích rồi tải tệp đó lên.
  3. Chuyển đến thẻ Package (Gói) rồi nhấp vào View public key (Xem khoá công khai).

Thẻ Gói trang tổng quan dành cho nhà phát triển

Khi cửa sổ bật lên mở, hãy làm theo các bước sau:

  1. Sao chép mã trong khoảng từ -----BEGIN PUBLIC KEY----- đến -----END PUBLIC KEY-----.
  2. Xoá các dòng mới để chuyển thành một dòng văn bản.

Cửa sổ bật lên về khoá công khai

Thêm mã vào manifest.json trong trường "key". Bằng cách này, tiện ích sẽ sử dụng cùng một mã nhận dạng.

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

So sánh mã nhận dạng

Mở trang Quản lý tiện ích tại chrome://extensions, nhớ bật Chế độ nhà phát triển rồi tải thư mục tiện ích chưa đóng gói lên. So sánh mã tiện ích trên trang quản lý tiện ích với mã mục trong Trang tổng quan dành cho nhà phát triển. Các giá trị này phải khớp nhau.

Mã của phần mở rộng trùng khớp

Tạo mã ứng dụng OAuth

Chuyển đến Bảng điều khiển API của Google và tạo một dự án mới. Sau khi sẵn sàng, hãy chọn Thông tin xác thực trong thanh bên, nhấp vào Tạo thông tin xác thực rồi chọn Mã ứng dụng khách OAuth.

Tạo thông tin đăng nhập cho tiện ích

Trên trang Tạo mã ứng dụng khách, hãy chọn Tiện ích của Chrome. Điền tên tiện ích và đặt mã tiện ích ở cuối URL trong trường Mã ứng dụng.

Điền thông tin về tiện ích

Hoàn tất bằng cách nhấp vào Tạo. Bảng điều khiển sẽ cung cấp một mã ứng dụng khách OAuth.

Đăng ký OAuth trong tệp kê khai

Đưa trường "oauth2" vào tệp kê khai tiện ích. Đặt mã ứng dụng khách OAuth đã tạo trong "client_id". Hiện tại, hãy cung cấp một chuỗi trống trong "scopes".

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

Bắt đầu quy trình OAuth đầu tiên

Đăng ký quyền identity trong tệp kê khai.

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

Tạo một tệp để quản lý quy trình OAuth có tên oauth.js và chứa mã sau.

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

Đặt một thẻ tập lệnh cho oauth.js ở đầu index.html.

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

Tải lại tiện ích rồi nhấp vào biểu tượng trình duyệt để mở index.html. Mở bảng điều khiển và nhấp vào nút "FriendBlock Contacts". Mã thông báo OAuth sẽ xuất hiện trong bảng điều khiển.

Xem mã thông báo trong bảng điều khiển

Bật Google People API

Quay lại bảng điều khiển API của Google rồi chọn Thư viện trên thanh bên. Tìm "Google People API", nhấp vào đúng kết quả rồi bật kết quả đó.

Bật API Mọi người

Thêm thư viện ứng dụng Google People API vào "scopes" trong tệp kê khai tiện ích.

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

Quay lại bảng điều khiển API của Google và quay lại thông tin xác thực. Nhấp vào "Tạo thông tin xác thực" và chọn "Khoá API" trong trình đơn thả xuống.

Tạo thông tin đăng nhập API Mọi người

Giữ lại khoá API đã tạo để sử dụng sau này.

Tạo yêu cầu API đầu tiên

Giờ đây, tiện ích có quyền, thông tin xác thực phù hợp và có thể uỷ quyền cho một người dùng Google, tiện ích này có thể yêu cầu dữ liệu thông qua API Mọi người. Hãy cập nhật mã trong oauth.js để khớp với thông tin bên dưới.

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)
          });
    });
  });
};

Thay thế API_KEY bằng khoá API được tạo qua bảng điều khiển API của Google. Tiện ích này phải ghi nhật ký một đối tượng JSON bao gồm một mảng people/account_id trong trường memberResourceNames.

Chặn khuôn mặt

Giờ đây, tiện ích này sẽ trả về danh sách danh bạ của người dùng, tiện ích này có thể thực hiện thêm các yêu cầu khác để truy xuất hồ sơ và thông tin của những người liên hệ đó . Tiện ích này sẽ sử dụng memberResourceNames để truy xuất thông tin ảnh của danh bạ của người dùng. Cập nhật oauth.js để đưa vào mã sau.

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);
                  });
            };
          });
    });
  });
};

Tải lại và quay lại tiện ích. Nhấp vào nút FriendBlock và ta-da! Sử dụng khuôn mặt của người liên hệ trong một khối.

Khuôn mặt của người liên hệ trong một khối