electron 拦截WebSocket消息

vfwfrxfs  于 2022-12-20  发布在  Electron
关注(0)|答案(5)|浏览(499)

对于 AJAX 请求,可以使用以下代码:

let oldXHROpen = window.XMLHttpRequest.prototype.open;
window.lastXhr = '';
window.XMLHttpRequest.prototype.open = function(method, url, async, user, password) {
  this.addEventListener('load', function() {
    window.lastXhr = this.responseText;
  });
  return oldXHROpen.apply(this, arguments);
};

lastXhr变量将保存最后一个响应。
但是如何才能让websockets也做到这一点呢?

p1iqtdky

p1iqtdky1#

你需要尽快做这个 Package
@brunoff你是对的,因为你总是可以在服务器之前通过傀儡窗口逻辑使用你的函数,或者你可以从MessageEvent本身劫持data

function listen(fn){
  fn = fn || console.log;

  let property = Object.getOwnPropertyDescriptor(MessageEvent.prototype, "data");
  
  const data = property.get;

  // wrapper that replaces getter
  function lookAtMessage() {

    let socket = this.currentTarget instanceof WebSocket;

    if (!socket) {
      return data.call(this);
    }

    let msg = data.call(this);

    Object.defineProperty(this, "data", { value: msg } ); //anti-loop
    fn({ data: msg, socket:this.currentTarget, event:this });
    return msg;
  }
  
  property.get = lookAtMessage;
  
  Object.defineProperty(MessageEvent.prototype, "data", property);
}

listen( ({data}) => console.log(data))

您可以尝试在this page上的控制台中放入代码并运行它,然后运行他们的WebSocket示例。

vcudknz3

vcudknz32#

要拦截消息,您必须监视onmessage = fnaddEventListener("message", fn)调用。
为了能够修改onmessage,我们首先必须覆盖全局WebSocket,下面是拦截传入消息的方法,但是您可以通过类似的方法监视send方法以拦截传出消息(客户端发送到服务器的消息)。
我使用Firebase在一个页面上测试了这个功能,它工作得很好,但是您必须在其他脚本之前初始化它,以确保WebSocket库(可以是socket.io、ws等)正在使用覆盖的WebSocket构造函数。

监视传入消息 * 并 * 修改data

最后,您可以在调用真实的的消息侦听器之前覆盖data-如果您无法控制页面功能,并且希望将自己的数据注入到消息侦听器中,这将非常方便。

const OriginalWebsocket = window.WebSocket
const ProxiedWebSocket = function() {
  console.log("Intercepting web socket creation")

  const ws = new OriginalWebsocket(...arguments)

  const originalAddEventListener = ws.addEventListener
  const proxiedAddEventListener = function() {
    if (arguments[0] === "message") {
      const cb = arguments[1]
      arguments[1] = function() {
        // Here you can get the actual data from the incoming messages
        // Here you can even change the data before calling the real message listener
        Object.defineProperty(e, "data", { value: 'your injected data' })
        console.log("intercepted", arguments[0].data)
        return cb.apply(this, arguments)
      }
    }
    return originalAddEventListener.apply(this, arguments)
  }
  ws.addEventListener = proxiedAddEventListener

  Object.defineProperty(ws, "onmessage", {
    set(func) {
      return proxiedAddEventListener.apply(this, [
        "message",
        func,
        false
      ]);
    }
  });
  return ws;
};

window.WebSocket = ProxiedWebSocket;

如果不需要修改数据,可以按照第二部分的答案进行。

在不修改数据的情况下监视传入消息

如果您想只监听消息,而不覆盖数据,事情就简单多了:

const OriginalWebsocket = window.WebSocket
const ProxiedWebSocket = function() {
  const ws = new OriginalWebsocket(...arguments)
  ws.addEventListener("message", function (e) {
    // Only intercept
    console.log(e.data)
  })
  return ws;
};
window.WebSocket = ProxiedWebSocket;

监视传出消息

以非常类似的方式,您可以代理用于向服务器发送数据的send方法。

const OriginalWebsocket = window.WebSocket
const ProxiedWebSocket = function() {
  const ws = new OriginalWebsocket(...arguments)
  const originalSend = ws.send
  const proxiedSend = function() {
    console.log("Intercepted outgoing ws message", arguments)
    // Eventually change the sent data
    // arguments[0] = ...
    // arguments[1] = ...
    return originalSend.apply(this, arguments)
  }
  ws.send = proxiedSend
  return ws;
};
window.WebSocket = ProxiedWebSocket;

如果有什么不清楚的地方,请随便问。

eulz3vhy

eulz3vhy3#

在一个与您的解决方案类似的解决方案中,window.XMLHttpRequest被替换为提供window.lastXhr的 Package 版本,我们将window.WebSockets替换为提供window.WebSocketMessages的 Package 版本,该 Package 版本提供从在此脚本之后创建的所有websocket接收到的所有消息和时间戳。

window.watchedWebSockets = [];
window.WebSocketMessages = [];

function WebSocketAttachWatcher(websocket) {
    websocket.addEventListener("message", (event)=>window.WebSocketMessages.push([event.data,Date.now()]));
    window.watchedWebSockets.push(websocket);
}

// here we replace WebSocket with a wrapped one, that attach listeners on 
window.WebSocketUnchanged = window.WebSocket;
window.WebSocket = function(...args) {
    const websocket = new window.WebSocketUnchanged(...args);
    WebSocketAttachWatcher(websocket);
    return websocket;
}

与XMLRequest的情况不同,WebSocket可能已经存在。如果你需要保证所有的websocket都能被捕获,那么你需要尽快做这个 Package 器。如果你做不到,那么有一个不太好的技巧来捕获已经存在的websocket:

// here we detect existing websockets on send event... not so trustable
window.WebSocketSendUnchanged = window.WebSocketUnchanged.prototype.send;
window.WebSocket.prototype.send = function(...args) {
    console.log("firstsend");
    if (!(this in window.watchedWebSockets))
        WebSocketAttachWatcher(this);
    this.send = window.WebSocketSendUnchanged; // avoid passing here again on next send
    window.WebSocketSendUnchanged.call(this, ...args);
}

这是不那么可信的,因为如果他们不发送,但接收,他们将保持不被注意。

vybvopom

vybvopom4#

如果您正在使用nodejs,则可以使用socket.io

yarn add socket.io

安装后,可以使用socket.io中间件

io.use(async (socket, next) => {
  try {
    const user = await fetchUser(socket);
    socket.user = user;
  } catch (e) {
    next(new Error("unknown user"));
  }
});
1dkrff03

1dkrff035#

简介

问题/bounty/op特别要求一个有信誉的源代码,我的建议是使用一个已知的成熟库,而不是一个定制的解决方案,这个库已经被社区使用、审计、分支和普遍使用,并且托管在github上。

第二种选择是自己卷(虽然不推荐),关于如何做,有很多优秀的答案涉及addEventListener

摇了摇

Wshaked是一个库(托管在github上),允许轻松拦截和修改WebSocket请求和消息事件。它已经被多次加星和分叉。
免责声明:我与具体项目没有任何关系。strong text
示例:

wsHook.before = function(data, url, wsObject) {
    console.log("Sending message to " + url + " : " + data);
}

// Make sure your program calls `wsClient.onmessage` event handler somewhere.
wsHook.after = function(messageEvent, url, wsObject) {
    console.log("Received message from " + url + " : " + messageEvent.data);
    return messageEvent;
}

从文档中,您将发现:

    • wsHook.before-函数(数据、URL、wsObject)**:

在调用实际WebSocket的send()方法之前调用。
此方法必须返回也可以修改的数据。

    • wsHook. after-函数(事件、URL、wsObject):**

在从WebSocket服务器接收MessageEvent之后、调用WebSocket的onmessage事件处理程序之前调用。

Web套接字添加事件侦听器

WebSocket对象支持.addEventListener()
请参见:Multiple Handlers for Websocket Javascript

相关问题