Below is an answer for errors when connecting from web3.js WebsocketProvider.
Short Answer
If there is client's host noted inside origin '<...>'
in message, just specify it with geth as geth --ws --wsorigins <...>
.
If the host field is empty, specify the Origin
header inside WebsocketProvider
's options like:
const wsProvider = new Web3.providers.WebsocketProvider("ws://localhost:8546", {
headers: {
Origin: "some_meaningful_name"
}
});
web3 = new Web3(wsProvider);
and run geth with geth --ws --wsorigins some_meaningful_name
.
Rationale
Please note that the below rationale especially focuses on empty origin ''
.
Basically, origin '<...>' not allowed on WS-RPC interface
is caused because geth defaults to only accept connections from http://localhost
, if not specified with --wsorigins
option. The error is also caused with empty ''
when websocket's Origin
header is not specified while geth client requires it.
websocket's Origin
is a header set by the browser. Why does such header exists in websocket protocol and why geth asks for it? This is to protect possible abuse and hijacking from other sites since WebSockets are not restrained by the same-origin policy(see this and this). But also, note that Origin
header is subject to be manipulated since it's only a header added by the browser.
The WebsocketProvider
that web3 1.0 provides now is a websocket for the node(dependent on WebSocket-Node). You can use it on the browser side too, but note that in a browser environment even if you manually pass Origin
header onto the provider(see final code section), browser will automatically override that value with the current host. So when connecting from a browser using websocket, what you need to make sure is that the expected host is added correctly onto geth's --wsorigins
.
On the other hand, when a websocket is used in node, Origin
header may not have a valid meaning, since the websocket connection from a node process is not really in a user-agent scenario where the script is provided by the domain. From the WebSocket-Node documentation:
origin
is an optional field that can be used in user-agent scenarios to identify the page containing any scripting content that caused the connection to be requested. (This seems unlikely in node.. probably should leave it null most of the time.)
This is why the web3 code left it undefined
by default. But still, you can set the Origin
header with the options
object(which is the 2nd param of WebsocketProvider
constructor) with headers
> Origin
key, which will eventually written into the Origin
header.
To sum up, one can just go with --wsorigins *
option for geth if security is not of much concern, or rather specify origin
header explicitly with some meaningful string(or the actual host) on the web3 websocket provider and pass the value onto geth's --wsorigins
. One easy option is to set the Origin
header as http://localhost
on web3 ws-provider, and run geth without --wsorigins
since geth defaults to accept connections from http://localhost
.
Adapted from my own comment on a similar issue