Используем Chrome Identity API

При создании расширения для Chrome довольно удобно аутентифицировать пользователя по логину в Chrome. Потому что если он совершил вход в свой аккаунт, то можно не требовать дополнительно логиниться в ваше приложение. Для этого Chrome предоставляет разработчикам расширений identity функционал.

Чтобы им воспользоваться нужно опубликовать черновик вашего расширения в Chrome Web Store для того, чтобы у вашего расширения появился id (вида: idhnkoehnkpmejapcxxxxlpfldsf, можно найти на странице расширения).

Затем нужно перейти в Google Cloud Console создать проект (либо выбрать существующий). На главной странице вашего проекта перейти в Api & Services.

Слева вкладка Credentials, нам туда.


Создаем новый креды: Create CredentialsOAuth 2.0 Client ID

Application type: Chrome extension
Item ID: id вашего расширения вида idhnkoehnkpmejapcxxxxlpfldsf
Также можно подтвердить что это ваше расширение.
Нажимаем создать.

В итоге после редиректа в таблице в графе ClientId будет ваш id, который нужно будет вставить в манифест (он вообще публичный, но в git его лучше не комитать).

Теперь для локальной разработки важно, чтобы id вашего приложения оставался постоянный (т к когда вы загружаете распакованное расширение при локальном дебаге, он меняется)
Для этого в Chrome Web Store во вкладке Пакет на странице с вашим расширением ищем графу Открытый ключ, кликаем, копируем.

Вставляем наши данные в манифест:
Открытый ключ
"key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKJHFDISJHFKJHDKJHSKJFHSJ"
Разрешения:
"permissions": ["identity", остальные ваши расзрешения]
ClientId из Cloud Console:

"oauth2": {
	"client_id": "YOUR_CLIENT_ID.apps.googleusercontent.com",
    "scopes": ["https://www.googleapis.com/auth/userinfo.email"]
 }

Готово!

Теперь можно запрашивать токен пользователя в content.js, при отправке запроса например:

function getAuthToken(res: (res: string) => void, rej: () => void) {
  chrome.identity.getAuthToken({ interactive: false }, (token) => {
  /// если возможно, запрашиваем без окна oauth2
    if (chrome.runtime.lastError || !token) {
      console.warn("Silent auth failed:", chrome.runtime.lastError?.message);
 
/// если не вышло, запрашиваем с попапом oauth2
      chrome.identity.getAuthToken(
        { interactive: true },
        (interactiveToken) => {
          if (chrome.runtime.lastError || !interactiveToken) {
            console.error(
              "Interactive auth failed:",
              chrome.runtime.lastError?.message
            );
            rej();
            return;
          }
/// вот наш токен
          res(interactiveToken);
        }
      );

      return;
    }
/// вот наш токен
    res(token);
  });
}

На сервере проверяем, что токен валидный через GET запрос на https://www.googleapis.com/oauth2/v3/tokeninfo?access_token=${token}

В ответе получим

{
    azp: '81800004758-xxxxxxxxx.apps.googleusercontent.com',
    /// проверим что aud совпадает с вашем clientid из cloud console
    aud: '818600004758-xxxxxx.apps.googleusercontent.com',
    sub: '101158204829854056900',
    scope: 'https://www.googleapis.com/auth/userinfo.email openid',
    exp: '1745297288',
    expires_in: '3598',
    email: 'test@gmail.com',
    email_verified: 'true',
    access_type: 'online'
}

Готово, тепрь вы можете бесшовно аутентифицировать ваших пользователей.

Подписывайтесь на мой канал в Telegram про разработку и не только.