Wilco Verhoef
Wilco Verhoef

Reputation: 90

How do I set a custom origin for socket.io-client connections?

I want to connect my node.js client (node-webkit) to a socket.io server that I do not have direct access to. The server requires a connection to match a certain origin in the request header, but I cannot find a way to change it.

This is what I have:

var io = require('socket.io-client');

socket = io.connect( url );

To reproduce, the socket.io package needs to be installed using npm

It connects to the server, sends some 'pings' and 'pongs' after which the server terminates the connection (as expected because of the wrong origin).

Note that I cannot change the server, so simply adding an origin to the white-list is no possibility.

 

Things I've tried so far

Using extraHeaders like this:

socket = io.connect( url, {extraHeaders: {origin: url}} )

..but that doesn't change the origin. I've tried to edit other/custom headers but the extraHeaders option doesn't seem to do anything.

 

I've also looked into the node cors module, but the documentation only provides examples on how to set an origin for express app requests, not socket.io.

 

And lastly I've simply tried to set the global origin variable to the right url, but that isn't picked up by socket.io.

 

Note: To check whether any of these methods work I looked at the 'Network' tab in the DevTools to see the request headers.

Upvotes: 2

Views: 4119

Answers (2)

pmg7670
pmg7670

Reputation: 141

For future reference, anyone using socket.io-client and having the same problem, you can resolve this by creating a tiny web-extension which is then added to your browser. You of course must add this as an installation condition of your app.

In the content-script and background script, add an intercepting request event handler. The handler can update the origin header value to the current tab source origin or whatever.

  1. content-script.js
(async () => {
  await browser.runtime.sendMessage({action: "setActiveTabOrigin"})
})();
  1. background.js
browser.runtime.onMessage.addListener(async (params) => {
  if (params.action == "setActiveTabOrigin") {
    window.origin = await browser.tabs.query({currentWindow: true})
      .then((tabs) => {
        for (var tab of tabs) {
          if (tab.active) {
            const url = new URL(tab.url)
            return url.origin
          }
        }
    })
  }
});

function rewriteWSHeaders(e) {
 for (var header of e.requestHeaders) {
   if (header.name.toLowerCase() == "origin") {
     if (header.value == "null") {
       console.log("!!! Setting request origin to the active tab url origin : ", window.origin)
       header.value = window.origin
     }
   }
 }
 return {requestHeaders: e.requestHeaders};  
}  

// For the API details, refer to [mozilla's docs][1]
browser.webRequest.onBeforeSendHeaders.addListener(
  rewriteWSHeaders,
  {urls:["ws://<socket.io-server.host>/*"], types:["websocket"]},
  ["blocking", "requestHeaders"]
);

Partial web-extension manifest.json :

  "background": {
    "scripts": ["background.js"]
  }

  "content_scripts": [
    {
      "matches": ["<remoteHost>/*"],
      "js": ["content-script.js"],
      "runAt": "document_start"
    }
  ]

  "permissions": [
    "<all_urls>",
    "webRequest",
    "webRequestBlocking",
    "tabs"
  ],

Other prerequisites not explained but easily looked up

  1. This option is only useful when you target a known remote host because the remote host must be added to the 'cors allowed origins' list, passed-in as a python-socket.io constuctor parameter.

  2. The web-extension origin must also be passed to this list

websock = socketio.AsyncServer(
      async_mode='asgi',
      logger=logger,
      cors_allowed_origins=[extOrigin, <remoteHost>])

Upvotes: 2

Ammar Mourad
Ammar Mourad

Reputation: 97

You don't need to change any thing from client side, it is a server side configuration.

If you have access to there server just add your origin to the IO Server origins list or set it to *.

here is a how to link from socket.io docs.

Upvotes: 1

Related Questions