📘
Webアプリでユーザー切り替えを簡単にするChrome拡張機能を作った
はじめに
- Webアプリを手動テストする際、複数ユーザーを操作する必要があり、ログイン/ログアウトが手間でした。
- Chrome拡張機能でセッションを切り替えれば、ログイン/ログアウトの手間を省けることに気づきました。
- 既存のChrome拡張機能もあるようですが、拡張機能のインストールにはリスクがあるため、今回は自作しました。
注意事項
- この記事の内容は、作成者の環境で動作確認していません。
- 誤りがあれば、ご指摘いただけると幸いです。
- ソースコードを利用する際は、内容を理解して使用してください。拡張機能は悪用される可能性もあるため、理解していないものをインストールしないでください。
- ソースコードの使用によって生じた不利益については責任を負いません。
- 今回のソースコードは localStorage と cookie のみを取得しています。sessionStorage など他の情報が必要な場合はソースコードを修正してください。
- 登録したトークン等の有効期限が切れると使用できなくなります。
ソースコード
manifest.json
{
"manifest_version": 3,
"name": "SwitchSession",
"version": "1.0",
"description": "",
"permissions": [
"activeTab",
"storage",
"cookies",
"scripting"
],
"host_permissions": [
"https://*/*"
],
"action": {
"default_title": "popup",
"default_popup": "popup.html"
}
}
popup.html
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
</head>
<body style="width: 500px;">
<select id="select"></select>
<button id="switch">切り替え</button>
<button id="delete">削除</button>
<div style="margin-top: 2em;">
<input type="text" id="name">
<button id="set">登録</button>
</div>
<script src="popup.js"></script>
</body>
</html>
popup.js
const selectDom = document.getElementById('select')
const nameInputDom = document.getElementById('name')
let currentTab
let sessions = {}
const displaySelectSessions = () => {
selectDom.innerHTML = ''
let html = ''
Object.keys(sessions).forEach((key) => {
html += `
<option value="${key}">
${key}
</option>
`
})
selectDom.insertAdjacentHTML('beforeend', html)
}
const setSession = async (session, name) => {
sessions = {
...sessions,
[name]: session
}
await chrome.storage.local.set({sessions})
}
const loadSessionByCurrentTab = async () => {
const [{result}] = await chrome.scripting.executeScript(
{
target: {tabId: currentTab.id},
function: () => {
let localStorageData = {}
for (let index = 0; index < localStorage.length; index++) {
const key = localStorage.key(index)
const value = localStorage.getItem(key)
localStorageData = {
...localStorageData,
[key]: value
}
}
return {
localStorage: localStorageData,
cookie: document.cookie
}
}
}
)
return result
}
const switchSessionByCurrentTab = async (session) => {
await chrome.scripting.executeScript(
{
target: {tabId: currentTab},
function: (session) => {
localStorage.clear()
Object.keys(session.localStorage).forEach((key) => {
localStorage.setItem(key, session.localStorage[key])
})
document.cookie = ''
session.cookie.split(';').forEach((cookie) => {
document.cookie = `${cookie}; path=/; secure`
})
},
args: [session]
}
)
}
document.getElementById('set').addEventListener('click', async () => {
const name = nameInputDom.value
nameInputDom.value = ''
const session = await loadSessionByCurrentTab()
await setSession(session, name)
displaySelectSessions()
})
document.getElementById('delete').addEventListener('click', async () => {
const key = selectDom.options[selectDom.selectedIndex].value
delete sessions[key]
await chrome.storage.local.set({sessions})
displaySelectSessions()
})
document.getElementById('switch').addEventListener('click', async () => {
const key = selectDom.options[selectDom.selectedIndex].value
await switchSessionByCurrentTab(sessions[key])
await chrome.tabs.update({url: new URL(currentTab.url).origin}) // ここではドメインを開いていますが、リロードのほうが良いかもしれません
})
document.addEventListener('DOMContentLoaded', async () => {
const items = await chrome.storage.local.get(['sessions'])
sessions = items.sessions ?? {}
displaySelectSessions()
const [tab] = await chrome.tabs.query({active: true, currentWindow: true})
currentTab = tab
})
使い方
拡張機能の読み込み
- chrome://extensions/ にアクセスし、デベロッパーモードをONにする
-
パッケージ化されていない拡張機能を読み込む
押下 - ソースコードを格納したフォルダを選択
- 読み込まれた拡張機能の
詳細
ボタン押下 -
ツールバーに固定する
をONにする
セッションの登録
- セッションを登録したいサイトを開き、登録したいユーザーでログインする
- ツールバーに表示されている読み込んだ拡張機能のアイコン押下
- テキストボックスにユニークな文字列を入力
※ユニークでない場合、登録内容が上書きされます。
※エラーハンドリング/バリデーションは行っていません。 - 登録ボタン押下
セッションの切り替え
- ログインしたいサイトを開く
- ツールバーに表示されている読み込んだ拡張機能のアイコン押下
- プルダウンから登録しているセッションを選択
- 切り替えボタン押下
セッションの削除
- ツールバーに表示されている読み込んだ拡張機能のアイコン押下
- プルダウンから登録しているセッションを選択
- 削除ボタン押下
Discussion