Реализация авторизации пользователя в браузерном расширении

Наша компания занимается разработкой, поддержкой и обслуживанием сайтов любой сложности. От простых одностраничных сайтов до масштабных кластерных систем построенных на микро сервисах. Опыт разработчиков подтвержден сертификатами от вендоров.

Разработка и обслуживание любых видов сайтов:

Информационные сайты или веб-приложения
Сайты визитки, landing page, корпоративные сайты, онлайн каталоги, квиз, промо-сайты, блоги, новостные ресурсы, информационные порталы, форумы, агрегаторы
Сайты или веб-приложения электронной коммерции
Интернет-магазины, B2B-порталы, маркетплейсы, онлайн-обменники, кэшбэк-сайты, биржи, дропшиппинг-платформы, парсеры товаров
Веб-приложения для управления бизнес-процессами
CRM-системы, ERP-системы, корпоративные порталы, системы управления производством, парсеры информации
Сайты или веб-приложения электронных услуг
Доски объявлений, онлайн-школы, онлайн-кинотеатры, конструкторы сайтов, порталы предоставления электронных услуг, видеохостинги, тематические порталы

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

Предлагаемые услуги
Показано 1 из 1 услугВсе 2065 услуг
Реализация авторизации пользователя в браузерном расширении
Средняя
~2-3 рабочих дня
Часто задаваемые вопросы

Наши компетенции:

Этапы разработки

Последние работы

  • image_website-b2b-advance_0.png
    Разработка сайта компании B2B ADVANCE
    1262
  • image_web-applications_feedme_466_0.webp
    Разработка веб-приложения для компании FEEDME
    1171
  • image_websites_belfingroup_462_0.webp
    Разработка веб-сайта для компании БЕЛФИНГРУПП
    874
  • image_ecommerce_furnoro_435_0.webp
    Разработка интернет магазина для компании FURNORO
    1094
  • image_crm_enviok_479_0.webp
    Разработка веб-приложения для компании Enviok
    831
  • image_bitrix-bitrix-24-1c_fixper_448_0.png
    Разработка веб-сайта для компании ФИКСПЕР
    851

Реализация авторизации пользователя в браузерном расширении

Авторизация в расширении — технически сложнее, чем в обычном веб-приложении: нет встроенных сессий, нельзя использовать httpOnly-куки, токены нужно хранить в chrome.storage, а OAuth2 flow требует специальной обработки.

OAuth2 через chrome.identity API

// manifest.json
{
  "permissions": ["identity", "storage"],
  "oauth2": {
    "client_id": "YOUR_GOOGLE_CLIENT_ID",
    "scopes": ["openid", "email", "profile"]
  }
}

// Авторизация через Google OAuth2
async function authenticateWithGoogle() {
  return new Promise((resolve, reject) => {
    chrome.identity.getAuthToken({ interactive: true }, async (token) => {
      if (chrome.runtime.lastError) {
        reject(chrome.runtime.lastError);
        return;
      }

      // Обмениваем Google token на токен нашего приложения
      const resp = await fetch('https://api.example.com/v1/auth/google', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ google_token: token }),
      });

      const { access_token, refresh_token } = await resp.json();

      await chrome.storage.local.set({
        access_token,
        refresh_token,
        token_expiry: Date.now() + 3600 * 1000,
      });

      resolve({ access_token });
    });
  });
}

Авторизация через собственный сервис (email/password)

// Открываем страницу авторизации в новой вкладке
async function loginWithCredentials() {
  const loginUrl = `https://app.example.com/extension-login?` +
    `redirect_uri=${encodeURIComponent('https://app.example.com/extension-callback')}`;

  // Открываем страницу логина
  chrome.tabs.create({ url: loginUrl });

  // Слушаем сообщение от страницы после авторизации
  return new Promise((resolve) => {
    const listener = (message) => {
      if (message.type === 'AUTH_SUCCESS') {
        chrome.runtime.onMessage.removeListener(listener);
        storeTokens(message.tokens);
        resolve(message.tokens);
      }
    };
    chrome.runtime.onMessage.addListener(listener);
  });
}

// На странице /extension-callback после авторизации:
// window.postMessage('extension-auth', ...) или chrome.runtime.sendMessage

Хранение и обновление токенов

class TokenManager {
  async getValidToken() {
    const stored = await chrome.storage.local.get(['access_token', 'refresh_token', 'token_expiry']);

    if (stored.access_token && stored.token_expiry > Date.now() + 60000) {
      return stored.access_token;
    }

    // Нужно обновить токен
    if (stored.refresh_token) {
      return this.refreshToken(stored.refresh_token);
    }

    throw new Error('Not authenticated');
  }

  async refreshToken(refreshToken) {
    const resp = await fetch('https://api.example.com/v1/auth/refresh', {
      method: 'POST',
      body: JSON.stringify({ refresh_token: refreshToken }),
    });

    const tokens = await resp.json();
    await chrome.storage.local.set({
      access_token:  tokens.access_token,
      refresh_token: tokens.refresh_token,
      token_expiry:  Date.now() + tokens.expires_in * 1000,
    });

    return tokens.access_token;
  }

  async logout() {
    await chrome.storage.local.remove(['access_token', 'refresh_token', 'token_expiry']);
    chrome.identity.clearAllCachedAuthTokens(() => {});
  }
}

Popup UI для авторизации

// popup.tsx
import { useState, useEffect } from 'react';

export function Popup() {
  const [user, setUser] = useState<User | null>(null);

  useEffect(() => {
    chrome.storage.local.get(['access_token'], async ({ access_token }) => {
      if (access_token) {
        const profile = await fetchUserProfile(access_token);
        setUser(profile);
      }
    });
  }, []);

  if (!user) {
    return (
      <div className="p-4 w-72">
        <h1 className="text-lg font-bold mb-4">Войти</h1>
        <button
          onClick={() => chrome.runtime.sendMessage({ action: 'login' })}
          className="btn-primary w-full"
        >
          Войти через Google
        </button>
      </div>
    );
  }

  return (
    <div className="p-4 w-72">
      <div className="flex items-center gap-3">
        <img src={user.avatar} className="w-8 h-8 rounded-full" />
        <span>{user.name}</span>
      </div>
    </div>
  );
}

Сроки

Авторизация в расширении с OAuth2 и refresh-токенами: 3–5 рабочих дней.