Summary: we're serving an Ethereum DApp from a webserver through HTTPS. The DApp connects to an Ethereum node through JSON RPC using web3.js, which uses HTTP (not HTTPS). How to deal with this in a good way?

It's good practice to serve web content over HTTPS, so our app is served from e.g. https://myhost/. Browsers enforce the HTTPS practice to such an extent that when a site/app is served over HTTPS, the browser requires that any further connections made by the app (including XMLHTTPRequests as done by web3.js) are also loaded over HTTPS.

Hence when the app is served over HTTPS, the browser blocks the calls to the Ethereum node (which are always HTTP) because of a "mixed content" error. Tested this on latest Chrome/Windows, but I imagine other browsers would give the same result. Basically it's a good thing that the browser does this.

As far as I know, the current Ethereum implementations have no functionality for serving the JSON RPC endpoint through HTTPS. Hence it could be worked around by wrapping the JSON RPC connection in HTTPS, e.g. by creating a small Node.js service.

What I want to know is how do others deal with this situation, and is there perhaps a simpler solution than the suggested workaround that I overlooked?

Example "Mixed content" error message:

Mixed Content: The page at 'https://myhost/user/login' was loaded over HTTPS, but requested an insecure XMLHttpRequest endpoint 'http://blockchain:8101/'. This request has been blocked; the content must be served over HTTPS.
HttpProvider.send @ httpprovider.js:77
finishedWithRewrite @ hooked-web3-provider.js:72
rewritePayloads @ hooked-web3-provider.js:107
next @ hooked-web3-provider.js:117
rewritePayloads @ hooked-web3-provider.js:122
send @ hooked-web3-provider.js:75
RequestManager.send @ requestmanager.js:73
Method.send @ method.js:168
SolidityFunction.call @ function.js:112
SolidityFunction.execute @ function.js:212
(anonymous function) @ VM6322:2
InjectedScript._evaluateOn @ VM6122:875
InjectedScript._evaluateAndWrap @ VM6122:808
InjectedScript.evaluate @ VM6122:664

To web3.js this presents itself as a connection error:

Uncaught Error: CONNECTION ERROR: Couldn't connect to node http://blockchain:8101, is it running?
at Object.module.exports.InvalidConnection (https://myhost/vendors/web3/dist/web3.js:3051:16)
at HookedWeb3Provider.HttpProvider.send (https://myhost/vendors/web3/dist/web3.js:4119:22)
at finishedWithRewrite (https://myhost/js/lib/hooked-web3-provider.js:72:91)
at HookedWeb3Provider.rewritePayloads (https://myhost/js/lib/hooked-web3-provider.js:107:18)
at next (https://myhost/js/lib/hooked-web3-provider.js:117:25)
at HookedWeb3Provider.rewritePayloads (https://myhost/js/lib/hooked-web3-provider.js:122:18)
at HookedWeb3Provider.send (https://myhost/js/lib/hooked-web3-provider.js:75:21)
at RequestManager.send (https://myhost/vendors/web3/dist/web3.js:5757:32)
at Method.send (https://myhost/vendors/web3/dist/web3.js:4898:59)
at SolidityFunction.call (https://myhost/vendors/web3/dist/web3.js:3915:31)

Note that I'm using a HookedWeb3Provider, but as the way the web3.js connects to the node is identical I don't expect that to make any difference.

Currently using web3.js 0.13.0.

  • Can you please clarify the question here? Forbidding HTTP/HTTPS mixed content is very common for browsers to do. Use all HTTP, or better yet, all HTTPS.
    – linagee
    Feb 1 '16 at 21:53
  • Thanks, clarified the title and question. Kept the error messages for search purposes. Essence is "this is a common case as I understand it, what are good ways for DApp developers to deal with it" rather than "how do I solve my particular problem right now". Feb 2 '16 at 11:20

The answer is you don't. Now I know you probably don't want to hear this but the HTTP JSON RPC was never meant to be used in such a way that it should be accessible from the outside. The RPC was brought in to existence so that you may develop against your own local node using your own browser.

What I suggest you do is that you setup a proxy that will proxy all requests to the locally running ethereum node instead of letting everyone directly interface with the ethereum node itself. This will give you controlled access and HTTPS.

  • Sure I do want to hear that, especially from someone who knows what he's talking about :) (making an understatement here). People are using JSON RPC externally though, as examples just have a quick look under the hood of app.augur.net and alpha.ujomusic.com. Will look at applying a proxy. Feb 2 '16 at 11:44
  • 1
    For those using Node.js, wrapping the JSON RPC endpoint in HTTPS using github.com/nodejitsu/node-http-proxy is easy and works well. Feb 2 '16 at 13:43

A picture paints a thouusand words - A Scalable, Resilient and Secured Environment for Go-Ethereum Nodes: Securing Go Ethereum (Geth) in Production with JSON RPC Enabled using HTTPS and NGINX

A Scalable, Resilient and Secured Environment for Go-Ethereum Nodes: Securing Go Ethereum (Geth Nodes) in Production with JSON RPC Enabled using HTTPS and NGINX

Sample NGINX configuration:

http { upstream nathanawgethnodes { server weight=3; server; server;
server; }

server { listen 443 ssl; server_name www.nathanaw-go-eth.com; keepalive_timeout 70;

    ssl_certificate     www.example.com.crt;
    ssl_certificate_key www.example.com.key;
    ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
    ssl_ciphers         HIGH:!aNULL:!MD5;

} }

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.