top of page
  • Writer's pictureAn Object Is A

Google OAuth2/OpenID Chrome Extension Login System

Updated: Nov 9, 2021



 

This tutorial is based on Chrome Extension Manifest Version 2.


Before we even touch a line of code, we need to setup our development workspace so that we have the ability to do two major things:

  1. Giving our specific Chrome Extension the ability to use Google’s APIs and Services.

  2. Gain the ability to interact with Google’s OAuth2 Endpoint.


Let’s Begin.

First, we’ll need to “register” our Chrome Extension with the Google store.


There are two ways to do this, we either officially upload our Chrome Extension to the Google Chrome Store and receive a unique key value for our extension or we “faux register” our extension with the Google Chrome Browser and receive a unique key that way. Since we don’t want to upload a development extension to the public store, we’ll opt for the latter method.

Navigate to the address “chrome://extensions” in your Chrome Browser.

Click on “Pack Extension” and choose the location of your Chrome Extension.

This will generate two files in the directory above your Chrome Extension location, a ‘crx’ and ‘pem’; we’re concerned with the ‘crx’ file.

Drag-and-drop the ‘crx’ file into the “chrome://extensions” page. You should get a prompt asking you to add the extension, click ‘Yes’.




Now, navigate to where your Chrome Extensions are located. For MacOS and Linux users, this will be different, but for Windows users you’re looking for something along the lines of,

C:\Users\<Your UserName>\AppData\Local\Google\Chrome\User Data\Default\Extensions

We’re looking for the folder with same name as your Chrome Extension ID. This id can be found back at your “chrome://extensions” page. Look for the “ID” attribute.

Enter into the folder with the same name as your Chrome Extension, enter into the version number folder and open the “manifest.json” file. Copy the “key” attribute.

This is our unique Chrome Extension key. Copy and paste that into the “manifest.json” of the Chrome Extension you’re actually developing. (the folder you chose for the “Pack Extension” step)



// manifest.json{
    "name": "Oauth2 test",
    "description": "",
    "version": "0.1.0",
    "manifest_version": 2,
    "key": "<your_key_here>",
    "icons": {
        "16": "./obj-16x16.png",
        "32": "./obj-32x32.png",
        "48": "./obj-48x48.png",
        "128": "./obj-128x128.png"
    },
    "background": {
        "scripts": [
            "./background.js",
            "./jsrsasign-all-min.js"
        ]
    },
    "options_page": "./options.html",
    "browser_action": {
        "default_popup": "popup.html"
    },
    "permissions": [
        "identity"
    ]
}

Note: We require the “identity” permission. We also use the ‘jsrsasign-all-min.js’ library to help us deal with the JWT(JSON Web Token). You can find that here: https://github.com/kjur/jsrsasign/releases/

Finally, remove your Chrome Extension from the browser (click “Remove”) and install the development extension by clicking “Load unpacked” and choosing the folder for your development extension.

This development extension now has the ability to use Google’s APIs and Services.


 

To gain authorization for Google’s OAuth2 Endpoint, we need to navigate into the Google Developer console and request an OAuth2 Client ID.

Navigate to “https://console.developers.google.com/" and if you haven’t already, create a project.

We have to do two things here…

Click on the “OAuth consent screen” link on the left.

Choose “External” and “Create”.

Just fill out the “Application name” field and “Save”.

The “OAuth Consent” screen tells the user we want access to their Google Data when they choose to login with their Google account.

Next, click on the “Credentials” link on the left.

Click the “Create Credentials” at the top of the page, choose “OAuth Client ID”.

Set the “Application type” to “Web application”, not “Chrome app”.

Fill in the “Name” field with anything you want then click on the “Add URI” at the bottom of the screen (the Redirect URI).

The URI should follow the pattern, https://<chrome-ext-id>.chromiumapp.org/

The “chrome-ext-id” is the same one from your “chrome://extensions” page.

Click “Create”.

This development extension now has the ability to interact with Google’s OAuth2 Endpoint.


 

Let’s login.

To demonstrate logging in, we’ll just place a button in the ‘popup.html’ page and attach a ‘popup-script.js’.



// popup.html<!DOCTYPE html>
<html lang="en"><head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
            width: 300px;
            height: auto;
        }div {
            position: relative;
            left: 50%;
            transform: translateX(-50%);
            width: 50%;
            height: 25%;
            padding: 5px;
            font-size: 2.5em;
            background-color: red;
            border-radius: 5px;
            text-align: center;
            color: white;
            font-family: monospace;
            font-weight: bold;
            margin-bottom: 15px;
            cursor: pointer;
            transition-duration: 0.3s;
        }div:hover {
            background-color: black;
            transform: translateX(-50%) scale(1.3);
        }
    </style>
</head><body>
    <h1>Sign-In With Your Google Account to Use This Extension</h1>
    <div id='sign-in'>Sign In</div>
    <button>User Status</button>
    <script src="./popup-script.js"></script>
</body></html>

When the user clicks on the button, we’ll send a message to our ‘background.js’ script to initiate third-party Google authentication.


// popup-script.jsdocument.querySelector('#sign-in')
  .addEventListener('click', function () {
     chrome.runtime.sendMessage({ message: 'login' }, function 
       (response) {
         if (response === 'success') window.close();
     });
});document.querySelector('button')
  .addEventListener('click', function () {
     chrome.runtime.sendMessage({ message: 'isUserSignedIn' }, 
       function (response) {
         alert(response);
    });
});

To let our users log in with their Google account, we use the ‘launchWebAuthFlow()’ API.

It allows us to request Google’s OAuth2 Endpoint, “https://accounts.google.com/o/oauth2/v2/auth".

We need to send 7 URI encoded query parameters with the URL:

  1. client_id: this is the OAuth2 Client ID given by the Google Developer console

  2. response_type: we need an ‘id_token’ from Google

  3. redirect_uri: once the user has logged into their Google account, we need to tell Google where to redirect the user (back to our Chrome Extension)

  4. scope: we have to tell the endpoint what we want to do with the user

  5. state: a random string used for security purposes

  6. prompt: makes sure the user is “prompted” with the screen allowing them to login with a Google account

  7. nonce: a random string used for security purposes

Once we have this information, we can construct the URL and fire it in ‘launchWebAuthFlow()’.



Note:

  1. We strip the ‘id_token’ out of the URL passed back to us in the callback of ‘launchWebAuthFlow()’.

  2. We can check that the ‘user_info.iss’ property’s value is one of two possible Google domains and that the ‘user_info.aud’ is the same as the OAuth2 Client ID. This check isn’t really needed as Google guarantees the token wasn’t tampered with.

  3. We keep track of the user’s sign in status in a variable, ‘user_signed_in’, on our side(background.js).

If the user successfully signs in, we switch the ‘popup.html’ to a popup-signed-in.html’ page.



// popup-signed-in.html<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <style>
        body {
            width: 300px;
            height: auto;
        }div {
            position: relative;
            left: 50%;
            transform: translateX(-50%);
            width: 50%;
            height: 25%;
            padding: 5px;
            font-size: 2.5em;
            background-color: red;
            border-radius: 5px;
            text-align: center;
            color: white;
            font-family: monospace;
            font-weight: bold;
            margin-bottom: 15px;
            cursor: pointer;
            transition-duration: 0.3s;
        }div:hover {
            background-color: black;
            transform: translateX(-50%) scale(1.3);
        }
    </style>
</head>
<body>
    <h1>Successfully Signed-In</h1>
    <div id='sign-out'>Sign Out</div>
    <button>User Status</button>
    <script src="./popup-signed-in-script.js"></script>
</body>
</html>

This allows the user to ‘sign out’.

// popup-signed-in-script.jsdocument.querySelector('#sign-out').addEventListener('click', function () {
    chrome.runtime.sendMessage({ message: 'logout' }, function (response) {
        if (response === 'success') window.close();
    });
});document.querySelector('button').addEventListener('click', function () {
    chrome.runtime.sendMessage({ message: 'isUserSignedIn' }, function (response) {
        alert(response);
    });
});


You can find the source files here.

If you would like a more in-depth guide, check out my full video tutorial on YouTube, An Object Is A. Be sure to follow us on Instagram and Twitter to keep up with our latest Web Development tutorials.

How to Use Google Login with Chrome Extensions | OAuth2/OpenID Connect


1,641 views0 comments

Recent Posts

See All
bottom of page