Синхронность JavaScript: объединение прослушивателя onAuthRequired и собственного массажа
У меня есть эта проблема... и я пытался передать пару имени пользователя и пароля в background.js моего расширения. Процесс идет следующим образом:
- Сервер учетных данных (CS) запускается с зашифрованными токенами учетных данных
- Selenium открывает браузер с пользовательским расширением
- Расширение запускается по AutRequired
- Native Messaging Host (NMH) запускается, затем получает сообщение "Ready"
- NMH использует простой протокол для запроса токенов из CS
- NMH расшифровывает токены
- NMH передает учетные данные в background.js
- background.js возвращает учетные данные в Chrome
- Магия аутентификации происходит на удаленном сервере
Я решил все до 6 ... может быть 7. Проблема в том, что я не могу на самом деле захватить то, что посылает NMH. Кажется, что или учетные данные не отформатированы правильно, поэтому они отклоняются, или есть проблема с тем, как сторона JavaScript собрана, и это просто случай неработающего кода. Также возможно, что то, что я намерен, совсем не возможно... хотя я сомневаюсь, что это так.
Я предоставлю столько кода, сколько смогу... и хотя я ценю любую помощь, я рад получить общий пример, который можно изменить в свое время.
Есть лучший подход? Я весь во внимании! Рад создать новый вопрос для решения других идей.
РЕДАКТИРОВАТЬ 1.0: я должен добавить, что при запуске предупреждение в строке 9 всплывающее окно. При изменении читать:
window.alert(String(response));
я получил [object Object]
РЕДАКТИРОВАТЬ 2.0: я изменил window.alert(String(response));
в window.alert(JSON.stringify(response));
и это дало ожидаемый результат: {"username":"\"some_user\"","password":"\"1Password\"}
Я ожидаю, что это будет переводить как '{username:"some_user", пароль:"1Password"}'
Кажется, существует проблема передачи значения ответа для кредитов, поскольку NMH вообще не запускается, когда я пытаюсь получить доступ к свойству имени пользователя / пароля кредитов за пределами обратного вызова. Это, вероятно, проблема сфер...
Редактировать 3.0: я нашел проблему - это проблема синхронности. Я нашел много, много вопросов по этому поводу - я отвечу на это, когда я придумаю работу вокруг себя. Не стесняйтесь ответить решением, если оно у вас есть.
Текущий background.js
(не работает)
chrome.webRequest.onAuthRequired.addListener(() => {
var hostName = "aardvark_nm_host";
var creds = null;
chrome.runtime.sendNativeMessage(
hostName,
{ text: "Ready" },
function(response){
window.alert("response");
console.log(response);
creds = JSON.parse(response);
}
);
return {authCredentials: creds};
},
{urls: ["<all_urls>"]},
['blocking']
);
Текущий aardvark_nm_host.py (возможно, работает)
#!/usr/bin/env python
from locksmith import decrypt_token, KEYFILE
import socket
import struct
import sys
import json
PORT = 9999
ADDR = 'localhost'
ERRMSG = {"username":"ERROR", "password":"password"}
def report_string(string):
def transceive(signal):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server = (ADDR, PORT)
sock.connect(server)
try:
sock.sendall(signal)
except Exception as e:
print >>sys.stderr, e
sock.close()
try:
sock.sendall(string)
sock.close()
except Exception as e:
print >>sys.stderr, e
sock.close()
transceive('S')
def get_tokens():
def recv_burst(sock):
total_data = []
while True:
data = sock.recv(1024)
if not data:
break
total_data.append(data)
return ''.join(total_data)
def transceive(signal):
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server = (ADDR, PORT)
sock.connect(server)
try:
sock.sendall(signal)
message = recv_burst(sock)
except Exception as e:
report_string(e)
finally:
sock.close()
return message
try:
username = transceive('U')
username = decrypt_token(username)
report_string(username)
except Exception as e:
report_string(str(e))
username = "TOKEN_ERROR"
try:
password = transceive('P')
password = decrypt_token(password)
report_string(password)
except Exception as e:
report_string(str(e))
password = "TOKEN_ERROR"
return {"username":username, "password":password}
def read_message():
text_length = sys.stdin.read(4)
if len(text_length) == 0:
sys.exit(0)
text_length = struct.unpack('@I', text_length)[0]
text = sys.stdin.read(text_length)
return json.loads(text)
def encode_message(message):
encoded_content = json.dumps(message)
encoded_length = struct.pack('@I', len(encoded_content))
return {'length': encoded_length, 'content': encoded_content}
def send_message(encoded_message):
sys.stdout.write(encoded_message['length'])
sys.stdout.write(encoded_message['content'])
sys.stdout.flush()
def interpretation(message):
return message["text"] == "Ready"
while True:
received_message = read_message()
report_string(received_message)
if interpretation(received_message):
creds = get_tokens()
send_message(encode_message(creds))
creds = None
else:
send_message(encode_message(ERRMSG))
Текущее расширение manifest.json
{
"version": "1.0.0",
"manifest_version": 2,
"name": "authvark",
"permissions": [
"<all_urls>",
"webRequest",
"webRequestBlocking",
"nativeMessaging"
],
"background": {
"scripts": ["background.js"],
"persistent": false
}
}
нативные-сообщения-хосты /manifest.json
{
"name": "aardvark_nm_host",
"description": "Intermediary Credential Host",
"path": "/path/to/aardvark_nm_host.py",
"type": "stdio",
"allowed_origins": [
"chrome-extension://.../"
]
}
2 ответа
Предоставление учетных данных вonAuthReauired
событие должно работать со следующим скриптом:
function callbackFn(details) {
return {
authCredentials: {
username: "%s",
password: "%s"
}
};
}
chrome.webRequest.onAuthRequired.addListener(
callbackFn,
{urls: ["<all_urls>"]},
['blocking']
);
Решением проблемы было использование обратных вызовов.
Я думал, что мне придется иметь дело с Обещаниями, над которыми я проделал большую работу... только чтобы найти гораздо более простой ответ.