Я использую скрипты контента
Я создал расширение Chrome, которое будет работать на любом количестве доменов, где у меня нет контроля, и расширение использует Firebase вход через контент-script.
Моя проблема в том, что Firebase сохраняет состояние, используя indexedDB , но это делает расширение уязвимым для вредоносных веб-сайтов, крадущих сеанс пользователя, читая indexedDB состояние (возможно, я здесь не так?).
Когда расширение активировано, я внедряю крошечное приложение реакции в DOM через контент-скрипт, который использует Firebase javacript sdk для получения данных и управления сеансами входа в систему.Я хотел бы, чтобы состояние входа в систему пользователей сохранялось, чтобы им не приходилось входить в систему каждый раз, когда они используют расширение (в противном случае, я думаю, я мог бы просто установить постоянство Firebase на NONE, чтобы предотвратить использование indexedDB ).
Я думаю, что если я смогу каким-то образом сохранить сеанс (возможно, refreshToken) в области хранения Chrome, а затем прочитать его при загрузке, чтобы повторно инициализировать сеанс пользователя, тогда сеанс будет более безопасным (не очень безопасным,но безопаснее, чем если бы я использовал indexedDB ).Даже если к хранилищу можно получить доступ, введя правильную папку на ПК, лучше хранить данные там, где только расширение может получить программный доступ к ним.
Вещи, которые я до сих пор пробовал
Ручной способ
Я пытался использовать конечную точку с маркером apiKey и обновления для получения новых учетных данных (ref: Как использовать refreshToken Firebase для повторной аутентификации? ), и это работаетхорошо.Я также смог получить refreshToken от объекта пользователя, возвращенного после выполнения signInWithEmailAndPassword()
.
Итак, последняя часть головоломки состоит в том, чтобы передать это обновленное состояние входа в Firebase SDK, чтобы иметь возможность использовать функции Firebase SDK, такие как прослушиватели изменений и т. Д. Но я не нашел способа сделать это. Кто-нибудь знает, возможно ли это?
Встроенный метод
Есть метод под названием signInAndRetrieveDataWithCredential
, который я пытался использовать.Функция входа возвращает объект учетных данных, который я пытался передать в signInAndRetrieveDataWithCredential
, чтобы возобновить сеанс пользователя, но метод возвращает ошибку, сообщающую, что объект недействителен.Вероятно, есть много вещей, которые не должны сохраняться в объекте учетных данных, так что это не предпочтительный способ, но в качестве последнего средства я мог бы рассматривать это как вариант. Но как более общий вопрос о Firebase, есть ли способ сохранить пользователей вошедшими в систему и сохранить их в таком месте, как chrome.storage?
Худший способ
Сохранение имени пользователя / пароля в хранилище Chrome возможно и даст расширению возможность входа пользователя при его открытии.Это, конечно, ужасный способ обойти проблему и на самом деле не вариант.Но я читал, что менеджер паролей Chrome также хранит пароли относительно небезопасные, , в чем разница между этим и хранением пароля для этого расширения в хранилище Chrome, возможно, с каким-то шагом обфускации, чтобы он не был четко читаемым?
** ОБНОВЛЕНИЕ **
Чтобы обойти эту проблему, я создал конечную точку для проверки и входа пользователей в систему с использованием пользовательских токенов.Он работает следующим образом:
- Пользователь входит в систему, сохраняет refreshToken в chrome.storage.sync
- , когда пользователь запускает дополнение во второй раз, когда я получаютокен из chrome storage.async
- отправляет токен в созданную мной функцию Firebase , которая использует метод обновления токена, описанный в разделе «Ручной способ»" выше.
- Если я получаю положительный результат при вызове конечной точки аутентификации из моей функции Firebase Я предполагаю, что токен действителен, и использую userId в возвращенных данных для создания пользовательского токена, который отправляется обратно.пользователю
- Используйте этот пользовательский токен, чтобы войти в систему, позвонив по номеру
firebase.auth().signInWithCustomToken(token)
Настраиваемая ссылка на токен: https://firebase.google.com/docs/auth/admin/create-custom-tokens#create_custom_tokens_using_the_firebase_admin_sdk
Однако приведенные выше вопросы по-прежнемуостаются:
- Можно ли сохранить сеанс пользователя, отличный от контекста firebase persist, и затем снова "активировать" сеанс пользователя, используя эти данные сеанса, когда пользователь возвращается?что-то вроде
signInWithRefreshToken
? - Есть ли встроенный способ, позволяющий пользователям входить в систему и хранить их в таком месте, как chrome.storage?(ответ, похоже, нет).
- Есть ли способ сохранить зашифрованную информацию для входа пользователя в chrome.storage.sync, которую можно считать достаточно безопасной?Информация используется при загрузке страницы и удаляется, когда учетные данные больше не действительны или пользователь выходит из системы.
** ВТОРОЕ ОБНОВЛЕНИЕ **
Когда я запускаю следующий скрипт натестовый сайт, размещенный на Firebase и с расширением, установленным локально, а не через веб-магазин Chrome, я получаю постоянный сеанс Firebase, включающий идентификатор обновления :
const request = window.indexedDB.open("firebaseLocalStorageDb", 1);
request.onerror = function (event) {
console.err("error fetching data", event);
};
request.onsuccess = function (dbEvent) {
const db = request.result;
const transaction = db.transaction(["firebaseLocalStorage"]);
console.log({transaction});
const objectStore = transaction.objectStore("firebaseLocalStorage");
if ('getAll' in objectStore) {
objectStore.getAll().onsuccess = function (getAllEvent) {
console.log(event.target.result);
};
}
};
Кроме того, когда я проверяю indexeddb, используя окно отладчика, indexeddb расширения имеет источник безопасности, установленный на страницу, через которую он загружен.
снимок источника безопасности в окне отладчика Chrome