¿Cuáles son las mejores prácticas para servir una DApp a través de HTTPS, conectándose a un nodo Ethereum usando JSON RPC/web3.js, que por defecto usa HTTP?

Resumen: estamos sirviendo una DApp de Ethereum desde un servidor web a través de HTTPS. La DApp se conecta a un nodo Ethereum a través de JSON RPC usando web3.js, que usa HTTP (no HTTPS). ¿Cómo lidiar con esto de una buena manera?

Es una buena práctica servir contenido web a través de HTTPS, por lo que nuestra aplicación se sirve desde, por ejemplo , https://myhost/ . Los navegadores imponen la práctica de HTTPS hasta tal punto que cuando un sitio/aplicación se sirve a través de HTTPS, el navegador requiere que cualquier otra conexión realizada por la aplicación (incluidas las solicitudes XMLHTTP como las realizadas por web3.js) también se cargue a través de HTTPS.

Por lo tanto, cuando la aplicación se sirve a través de HTTPS, el navegador bloquea las llamadas al nodo Ethereum (que siempre son HTTP) debido a un error de "contenido mixto". Probé esto en la última versión de Chrome/Windows, pero imagino que otros navegadores darían el mismo resultado. Básicamente, es bueno que el navegador haga esto.

Hasta donde yo sé, las implementaciones actuales de Ethereum no tienen funcionalidad para servir el punto final JSON RPC a través de HTTPS. Por lo tanto, podría solucionarse envolviendo la conexión JSON RPC en HTTPS, por ejemplo, creando un pequeño servicio Node.js.

Lo que quiero saber es cómo lidian los demás con esta situación, y ¿existe quizás una solución más simple que la solución alternativa sugerida que pasé por alto?

Ejemplo de mensaje de error "Contenido mixto":

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

Para web3.js esto se presenta como un error de conexión:

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)

Tenga en cuenta que estoy usando un HookedWeb3Provider, pero como la forma en que web3.js se conecta al nodo es idéntica, no espero que eso haga ninguna diferencia.

Actualmente usando web3.js 0.13.0.

¿Puede aclarar la pregunta aquí? La prohibición de contenido mixto HTTP/HTTPS es muy común para los navegadores. Usa todo HTTP, o mejor aún, todo HTTPS.
Gracias, aclaró el título y la pregunta. Mantuvo los mensajes de error para propósitos de búsqueda. La esencia es "este es un caso común tal como lo entiendo, cuáles son las buenas formas para que los desarrolladores de DApp lo aborden" en lugar de "cómo resuelvo mi problema particular en este momento".

Respuestas (2)

La respuesta es que no. Ahora sé que probablemente no quiera escuchar esto, pero el HTTP JSON RPC nunca fue diseñado para usarse de tal manera que debería ser accesible desde el exterior. El RPC se creó para que pueda desarrollarse en su propio nodo local utilizando su propio navegador.

Lo que sugiero que haga es que configure un proxy que enviará todas las solicitudes al nodo ethereum que se ejecuta localmente en lugar de permitir que todos interactúen directamente con el nodo ethereum. Esto le dará acceso controlado y HTTPS.

Seguro que quiero escuchar eso, especialmente de alguien que sabe de lo que está hablando :) (quedándose corto aquí). Sin embargo, la gente está usando JSON RPC externamente, como ejemplos, solo eche un vistazo rápido debajo del capó de app.augur.net y alpha.ujomusic.com . Examinará la aplicación de un proxy.
Para aquellos que usan Node.js, envolver el extremo JSON RPC en HTTPS usando github.com/nodejitsu/node-http-proxy es fácil y funciona bien.

Una imagen vale más que mil palabras: un entorno escalable, resistente y seguro para nodos Go-Ethereum: protección de Go Ethereum (Geth) en producción con JSON RPC habilitado mediante HTTPS y NGINX

Un entorno escalable, resistente y seguro para nodos Go-Ethereum: protección de Go Ethereum (nodos Geth) en producción con JSON RPC habilitado mediante HTTPS y NGINX

Ejemplo de configuración de NGINX:

http { upstream nathanawgethnodes { servidor 127.0.0.1:8545 peso=3; servidor 127.0.0.2:8545; servidor 127.0.0.3:8545;
servidor 127.0.0.4:8545; }

servidor { escucha 443 ssl; nombre_servidor 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;

} }