Реалізація авторизації користувача у браузерному розширенні

Наша компанія займається розробкою, підтримкою та обслуговуванням сайтів будь-якої складності. Від простих односторінкових сайтів до масштабних кластерних систем, побудованих на мікро сервісах. Досвід розробників підтверджено сертифікатами від вендорів.

Розробка та обслуговування будь-яких видів сайтів:

Інформаційні сайти або веб-програми
Сайти візитки, 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/пароль)

// Відкриваємо сторінку авторизації в новій вкладці
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 робочих днів.