Distribuzione sicura delle applicazioni NodeJS

Cosa: Le app NodeJS possono essere distribuite come binari? vale a dire. compilate l’app .js tramite V8 nel suo binario nativo e distribuite il binario ai client? (se hai accesso totale al server NodeJS) … o stai minimizzando il codice tutto quello che puoi fare?

Perché: realizziamo applicazioni serveride in NodeJS per i client, che devono essere spesso ospitate sui server del cliente. Distribuire il codice sorgente significa che i clienti possono facilmente rubare la nostra soluzione e smettere di pagare le tasse di licenza. Questo apre la possibilità di un facile reverse engineering o riutilizzo delle nostre app senza la nostra consapevolezza.

Sì, puoi creare un formato binario. V8 ti consente di precompilare JavaScript. Si noti che questo potrebbe avere un sacco di strani effetti collaterali sulle ipotesi fatte dal nodo core.

Distribuire il codice sorgente significa che i clienti possono facilmente rubare la nostra soluzione e smettere di pagare le tasse di licenza.

Solo perché il binario viene distribuito non ti protegge dal furto dei againsts. Possono ancora rubare il codice binario o smontarlo. Questa è la protezione attraverso l’oscurità che non è affatto una protezione.

È meglio offrire loro un’app thin client che comunichi con il server e mantenga il tuo codice server sicuro non cedendolo.

Sì, è ansible, usa questo ramo (basato su 0.8.18) e ogni codice js che inserisci in “deps / v8 / src / extra-snapshot.js” sarà compilato in anticipo nel codice macchina e incorporato nella v8 come parte della normale inizializzazione dell’object incorporato. Dovrai creare nodejs per ogni piattaforma che intendi distribuire.

Il codice snapshot viene eseguito molto presto nell’inizializzazione v8 e non è ansible accedere agli oggetti incorporati nel ‘corpo del modulo’. Quello che puoi fare è mettere tutto il tuo codice all’interno di una funzione di inizializzazione globale da chiamare in seguito. Ex:

// 'this' points to the same as the object referenced by // 'global' in normal nodejs code. // at this point it has nothing defined in it, so in order to use // global objects a reference to it is needed. var global = this; global.initialize = function() { // You have to define all global objects you use in your code here; var Array = global.Array; var RegExp = global.RegExp; var Date = global.Date; // See ECMAScript v5 standard global objects for more // Also define nodejs global objects: var console = global.console; var process = global.process; // Your code goes embedded here }; 

Inoltre, questo presuppone che l’intero codice sia definito in un singolo file, quindi se il progetto utilizza il sistema del modulo nodejs (richiede) è necessario scrivere uno script che combini tutti i file in uno e avvolga ciascun file in una chiusura che possa ingannare il tuo codice nel pensare che sia un normale modulo nodejs. Probabilmente ogni chiusura del modulo esporrà una funzione require, e questa funzione dovrebbe decidere quando debind allo standard ‘global.require’ o restituire le esportazioni dagli altri moduli incorporati. Guarda come vengono implementati i sistemi di moduli javascript per le idee (requirejs è un buon esempio).

Questo renderà il tuo codice più difficile da eseguire il debug poiché non vedrai tracce di stack per il codice nativo.

AGGIORNARE:

Anche usando le istantanee v8 il codice viene incorporato nel binario node.js perché v8 preferisce la compilazione lazy. Vedi questo per maggiori informazioni.

EncloseJS .

Ottieni un binario completamente funzionale senza fonti.

Il codice JavaScript viene trasformato in codice nativo in fase di compilazione utilizzando il compilatore interno V8. Quindi, le tue fonti non sono obbligate ad eseguire il binario e non sono pacchettizzate.

Il codice nativo perfettamente ottimizzato può essere generato solo in fase di esecuzione in base alla macchina del cliente. Senza queste informazioni, EncloseJS può generare solo codice “non ottimizzato”. Funziona circa 2 volte più lentamente di NodeJS.

Inoltre, il codice runtime node.js viene inserito all’interno dell’eseguibile (insieme al codice) per supportare l’API del nodo per l’applicazione in fase di esecuzione.

Casi d’uso:

  • Crea una versione commerciale della tua applicazione senza fonti.
  • Crea una versione demo / di valutazione / di prova della tua app senza fonti.
  • Crea una sorta di archivio auto-estraente o programma di installazione.
  • Creare un’applicazione GUI con sorgente chiusa utilizzando il nodo-spinta.
  • Non è necessario installare node e npm per distribuire l’applicazione compilata.
  • Non è necessario scaricare centinaia di file tramite l’installazione di npm per distribuire l’applicazione. Distribuirlo come un singolo file indipendente.
  • Metti le tue risorse all’interno dell’eseguibile per renderlo ancora più portabile. Metti alla prova la tua app contro la nuova versione del nodo senza installarla.

Attualmente sto studiando la stessa cosa e sto guardando Nexe che afferma di essere in grado di “creare un singolo eseguibile dalle tue app node.js”.

Non posso dirti se è ancora buono, ma ho pensato che valesse la pena di condividerlo già.

V8 genera internamente il codice macchina nativo e lo esegue. Guarda qui: https://github.com/v8/v8-git-mirror/blob/master/src/compiler.cc#L1178 . Questa funzione è utilizzata in EncloseJS . EncloseJS analizza i sorgenti del progetto node.js, raggruppa le dipendenze e crea un eseguibile binario. Le fonti non sono incluse nel codice macchina compilato solo in binario.