Firebase を使用した Chrome 拡張機能での Google 認証

WBOY
リリース: 2024-09-06 06:41:31
オリジナル
981 人が閲覧しました

Google Authentication in a Chrome Extension with Firebase

Google の公式ガイドにはいくつかの重要な手順が欠けているため、このガイドを作成しています。以下にリンクしています。

Chrome 拡張機能で Firebase を使用して認証する

これはどのオペレーティング システムでも動作します。このガイドでは Mac OS

を使用します。

前提条件

  • Google Chrome ブラウザ
  • Google アカウント
  • Chrome ウェブストア デベロッパー アカウント (1 回限りの料金 5 ドル)
  • Node.js と npm がインストールされています

ステップ 1: プロジェクト構造を作成する

a) プロジェクトの新しいディレクトリを作成します。

mkdir firebase-chrome-auth
cd firebase-chrome-auth
ログイン後にコピー

b) 2 つのサブディレクトリを作成します:

mkdir chrome-extension
mkdir firebase-project
ログイン後にコピー

ステップ 2: Firebase プロジェクトをセットアップする

a) Firebase コンソールに移動します。
b) [プロジェクトを追加] をクリックし、手順に従って新しいプロジェクトを作成します。
c) 作成したら、[Web] をクリックして Web アプリをプロジェクトに追加します。
d) ニックネーム (例: 「Chrome Extension Auth」) を使用してアプリを登録します。
e) Firebase 構成オブジェクトをコピーします。これは後で必要になります。

const firebaseConfig = {
  apiKey: "example",
  authDomain: "example.firebaseapp.com",
  projectId: "example",
  storageBucket: "example",
  messagingSenderId: "example",
  appId: "example"
};
ログイン後にコピー

f) firebase-project ディレクトリに移動します
cd firebase-プロジェクト
g) 新しい npm プロジェクトを初期化します
npm init -y
h) Firebase をインストールします:
npm install firebase
i) firebase-project/index.html
にindex.html ファイルを作成します。

<!DOCTYPE html>
<html>
 <head>
  <title>Firebase Auth for Chrome Extension</title>
 </head>
 <body>
  <h1>Firebase Auth for Chrome Extension</h1>
  <script type="module" src="signInWithPopup.js"></script>
 </body>
</html>
ログイン後にコピー

j) firebase-project/signInWithPopup.js
にsignInWithPopup.js ファイルを作成します。

import { initializeApp } from 'firebase/app';
import { getAuth, signInWithPopup, GoogleAuthProvider } from 'firebase/auth';

const firebaseConfig = {
  // Your web app's Firebase configuration
  // Replace with the config you copied from Firebase Console
};

const app = initializeApp(firebaseConfig);
const auth = getAuth();

// This gives you a reference to the parent frame, i.e. the offscreen document.
const PARENT_FRAME = document.location.ancestorOrigins[0];

const PROVIDER = new GoogleAuthProvider();

function sendResponse(result) {
  window.parent.postMessage(JSON.stringify(result), PARENT_FRAME);
}

window.addEventListener('message', function({data}) {
  if (data.initAuth) {
    signInWithPopup(auth, PROVIDER)
      .then(sendResponse)
      .catch(sendResponse);
  }
});
ログイン後にコピー

k) Firebase プロジェクトをデプロイします

npm install -g firebase-tools
firebase login
firebase init hosting
firebase deploy
ログイン後にコピー

展開後に提供されるホスティング URL に注目してください。これは Chrome 拡張機能に必要です。

ステップ 3: Chrome 拡張機能をセットアップする

a) chrome-extension ディレクトリに移動します
cd ../chrome-extension

b) chrome-extension/manifest.json
にmanifest.json ファイルを作成します。

{
  "manifest_version": 3,
  "name": "Firebase Auth Extension",
  "version": "1.0",
  "description": "Chrome extension with Firebase Authentication",
  "permissions": [
    "identity",
    "storage",
    "offscreen"
  ],
  "host_permissions": [
    "https://*.firebaseapp.com/*"
  ],
  "background": {
    "service_worker": "background.js",
    "type": "module"
  },
  "action": {
    "default_popup": "popup.html"
  },
  "web_accessible_resources": [
    {
      "resources": ["offscreen.html"],
      "matches": ["<all_urls>"]
    }
  ],
  "oauth2": {
    "client_id": "YOUR-ID.apps.googleusercontent.com",
    "scopes": [
      "openid", 
      "email", 
      "profile"
    ]
  },
  "key": "-----BEGIN PUBLIC KEY-----\nYOURPUBLICKEY\n-----END PUBLIC KEY-----"
}
ログイン後にコピー

c) chrome-extension/popup.html
に Popup.html ファイルを作成します。

<!DOCTYPE html>
<html>
<head>
    <title>Firebase Auth Extension</title>
</head>
<body>
    <h1>Firebase Auth Extension</h1>
    <div id="userInfo"></div>
    <button id="signInButton">Sign In</button>
    <button id="signOutButton" style="display:none;">Sign Out</button>
    <script src="popup.js"></script>
</body>
</html>
ログイン後にコピー

d) chrome-extension/popup.js
に Popup.js ファイルを作成します。

document.addEventListener('DOMContentLoaded', function() {
    const signInButton = document.getElementById('signInButton');
    const signOutButton = document.getElementById('signOutButton');
    const userInfo = document.getElementById('userInfo');

    function updateUI(user) {
        if (user) {
            userInfo.textContent = `Signed in as: ${user.email}`;
            signInButton.style.display = 'none';
            signOutButton.style.display = 'block';
        } else {
            userInfo.textContent = 'Not signed in';
            signInButton.style.display = 'block';
            signOutButton.style.display = 'none';
        }
    }

    chrome.storage.local.get(['user'], function(result) {
        updateUI(result.user);
    });

    signInButton.addEventListener('click', function() {
        chrome.runtime.sendMessage({action: 'signIn'}, function(response) {
            if (response.user) {
                updateUI(response.user);
            }
        });
    });

    signOutButton.addEventListener('click', function() {
        chrome.runtime.sendMessage({action: 'signOut'}, function() {
            updateUI(null);
        });
    });
});
ログイン後にコピー

e) chrome-extension/background.js
にbackground.js ファイルを作成します。

const OFFSCREEN_DOCUMENT_PATH = 'offscreen.html';
const FIREBASE_HOSTING_URL = 'https://your-project-id.web.app'; // Replace with your Firebase hosting URL

let creatingOffscreenDocument;

async function hasOffscreenDocument() {
    const matchedClients = await clients.matchAll();
    return matchedClients.some((client) => client.url.endsWith(OFFSCREEN_DOCUMENT_PATH));
}

async function setupOffscreenDocument() {
    if (await hasOffscreenDocument()) return;

    if (creatingOffscreenDocument) {
        await creatingOffscreenDocument;
    } else {
        creatingOffscreenDocument = chrome.offscreen.createDocument({
            url: OFFSCREEN_DOCUMENT_PATH,
            reasons: [chrome.offscreen.Reason.DOM_SCRAPING],
            justification: 'Firebase Authentication'
        });
        await creatingOffscreenDocument;
        creatingOffscreenDocument = null;
    }
}

async function getAuthFromOffscreen() {
    await setupOffscreenDocument();
    return new Promise((resolve, reject) => {
        chrome.runtime.sendMessage({action: 'getAuth', target: 'offscreen'}, (response) => {
            if (chrome.runtime.lastError) {
                reject(chrome.runtime.lastError);
            } else {
                resolve(response);
            }
        });
    });
}

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
    if (message.action === 'signIn') {
        getAuthFromOffscreen()
            .then(user => {
                chrome.storage.local.set({user: user}, () => {
                    sendResponse({user: user});
                });
            })
            .catch(error => {
                console.error('Authentication error:', error);
                sendResponse({error: error.message});
            });
        return true; // Indicates we will send a response asynchronously
    } else if (message.action === 'signOut') {
        chrome.storage.local.remove('user', () => {
            sendResponse();
        });
        return true;
    }
});
ログイン後にコピー

f) chrome-extension/offscreen.html
に offscreen.html ファイルを作成します。

<!DOCTYPE html>
<html>
<head>
    <title>Offscreen Document</title>
</head>
<body>
    <script src="offscreen.js"></script>
</body>
</html>
ログイン後にコピー

g) _chrome-extension/offscreen.js
に offscreen.js ファイルを作成します。 _

const FIREBASE_HOSTING_URL = 'https://your-project-id.web.app'; // Replace with your Firebase hosting URL

const iframe = document.createElement('iframe');
iframe.src = FIREBASE_HOSTING_URL;
document.body.appendChild(iframe);

chrome.runtime.onMessage.addListener((message, sender, sendResponse) => {
    if (message.action === 'getAuth' && message.target === 'offscreen') {
        function handleIframeMessage({data}) {
            try {
                const parsedData = JSON.parse(data);
                window.removeEventListener('message', handleIframeMessage);
                sendResponse(parsedData.user);
            } catch (e) {
                console.error('Error parsing iframe message:', e);
            }
        }

        window.addEventListener('message', handleIframeMessage);
        iframe.contentWindow.postMessage({initAuth: true}, FIREBASE_HOSTING_URL);
        return true; // Indicates we will send a response asynchronously
    }
});
ログイン後にコピー

ステップ 4: Firebase 認証を構成する

a) Firebase コンソールで、[認証] > [認証] に移動します。サインイン方法。
b) Google をサインイン プロバイダーとして有効にします。
c) Chrome 拡張機能の ID を承認済みドメイン リストに追加します:
形式は次のとおりです: chrome-extension://YOUR_EXTENSION_ID
拡張機能 ID は、解凍された拡張機能として読み込んだ後、Chrome の拡張機能管理ページで確認できます。

ステップ 5: 拡張機能をロードしてテストする

a) Google Chrome を開き、chrome://extensions/ に移動します。
b) 右上隅の「開発者モード」を有効にします。
c) [解凍してロード] をクリックし、Chrome 拡張機能のディレクトリを選択します。
d) Chrome のツールバーの拡張機能アイコンをクリックしてポップアップを開きます。
e) [サインイン] ボタンをクリックし、認証フローをテストします。

トラブルシューティング

CORS の問題が発生した場合は、Firebase ホスティング URL がbackground.js と offscreen.js の両方で正しく設定されていることを確認してください。

Chrome 拡張機能の ID が Firebase の承認済みドメインに正しく追加されていることを確認してください。

ポップアップ、バックグラウンド スクリプト、オフスクリーン ドキュメントのコンソール ログでエラー メッセージがないか確認してください。

結論

これで、オフスクリーン ドキュメントで Firebase Authentication を使用してサインイン プロセスを処理する Chrome 拡張機能が完成しました。この設定により、機密性の高い Firebase 設定の詳細を拡張コード内で直接公開することなく、安全な認証が可能になります。

拡張機能を公開する前に、プレースホルダーの値 (YOUR_EXTENSION_ID、YOUR-CLIENT-ID、YOUR_PUBLIC_KEY、your-project-id など) を必ず実際の値に置き換えてください。

以上がFirebase を使用した Chrome 拡張機能での Google 認証の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

ソース:dev.to
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート