web-dev-qa-db-ja.com

NodeJSアプリケーションの安全な配布

What: NodeJSアプリをバイナリとして配布できますか?すなわち。 V8を介して.jsアプリをネイティブバイナリにコンパイルし、クライアントにバイナリを配布しますか? (NodeJSサーバーへの完全なアクセス権がある場合)...またはコードをできる限り縮小していますか?

理由:クライアント用にNodeJSでサーバーサイドアプリケーションを構築します。これは、多くの場合、クライアントのサーバーでホストする必要があります。ソースコードの配布は、クライアントが簡単にソリューションを盗み、ライセンス料の支払いを停止できることを意味します。これにより、気付かないうちにアプリを簡単にリバースエンジニアリングまたは再利用できる可能性が広がります。

61
Robinicks

はい、バイナリ形式を作成できます。 V8では、JavaScriptをプリコンパイルできます。これには、ノードコアによって行われた仮定に対する奇妙な副作用がたくさんあることに注意してください。

ソースコードの配布は、クライアントが簡単にソリューションを盗み、ライセンス料の支払いを停止できることを意味します。

バイナリを配布したからといって、盗難から身を守ることはできません。バイナリコードを盗んだり、逆アセンブルしたりできます。これは、隠蔽による保護であり、まったく保護されません。

サーバーと通信するシンクライアントアプリを提供し、サーバーコードを公開しないことでサーバーコードを安全に保つ方が良いでしょう。

22
Raynos

はい、可能です。これは branch (0.8.18に基づいて)を使用し、「deps/v8/src/extra-snapshot.js」に配置したjsコードは事前にコンパイルされます通常の組み込みオブジェクトの初期化の一部としてv8に組み込まれ、マシンコードに組み込まれます。製品をデプロイする予定のプラットフォームごとにnodejsをビルドする必要があります。

スナップショットコードはv8初期化の非常に早い段階で実行され、「モジュール本体」の組み込みオブジェクトにアクセスできません。できることは、後で呼び出すために、すべてのコードをグローバル初期化関数内に配置することです。例:

// '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
};

また、これはコード全体が単一のファイルで定義されていることを前提としているため、プロジェクトでnodejsモジュールシステムを使用する場合(必要な場合)、すべてのファイルを1つに結合し、各ファイルをクロージャーでラップするスクリプトを記述する必要があります通常のnodejsモジュールであると考えるコード。おそらく、各モジュールクロージャーはrequire関数を公開し、この関数は標準の 'global.require'に委任するか、他の埋め込みモジュールからエクスポートを返すかを決定する必要があります。 javascriptモジュールシステムがアイデアのためにどのように実装されているかを確認してください(requirejsが良い例です)。

これにより、ネイティブコードのスタックトレースが表示されないため、コードのデバッグが難しくなります。

更新:

V8は遅延コンパイルを好むため、v8スナップショットを使用してもコードはnode.jsバイナリに埋め込まれます。詳細については、 this を参照してください。

23

EncloseJS

ソースなしで完全に機能するバイナリを取得します。

JavaScriptコードは、V8内部コンパイラーを使用してコンパイル時にネイティブコードに変換されます。したがって、ソースをバイナリを実行する必要はなく、パッケージ化されていません。

完全に最適化されたネイティブコードは、クライアントのマシンに基づいて実行時にのみ生成できます。その情報がなければ、EncloseJSは「最適化されていない」コードのみを生成できます。 NodeJSの約2倍の速度で実行されます。

また、実行時にアプリケーションのノードAPIをサポートするために、node.jsランタイムコードが(コードと共に)実行可能ファイル内に配置されます。

ユースケース:

  • ソースなしでアプリケーションの商用バージョンを作成します。
  • ソースなしでアプリのデモ/評価/試用版を作成します。
  • 何らかの自己解凍アーカイブまたはインストーラーを作成します。
  • Node-thrustを使用して、クローズドソースGUIアプリケーションを作成します。
  • コンパイルされたアプリケーションをデプロイするためにノードとnpmをインストールする必要はありません。
  • アプリケーションをデプロイするためにnpm installを介して数百のファイルをダウンロードする必要はありません。単一の独立したファイルとして展開します。
  • アセットを実行可能ファイルに入れて、さらに移植性を高めます。アプリをインストールせずに、新しいノードバージョンに対してテストします。
8
Robinicks

現在、同じことを調査しており、「node.jsアプリから単一の実行可能ファイルを作成できる」と主張している nexe を調べています。

まだ良いかどうかはわかりませんが、すでに共有する価値があると思いました。

3
kvz

V8は、内部でネイティブマシンコードを生成して実行します。ここをご覧ください: https://github.com/v8/v8-git-mirror/blob/master/src/compiler.cc#L1178 この機能は EncloseJS で使用されます。 EncloseJSは、node.jsプロジェクトのソースを解析し、依存関係をバンドルして、実行可能バイナリを作成します。ソースはバイナリに含まれません-コンパイルされたマシンコードのみ。

2
Igor Klopov

配布前に、pkgを使用してNode.jsアプリのバイナリバージョンを作成しています。

https://github.com/zeit/pkg

ライセンスキーチェックを追加するには、 Cryptlex を使用します。

https://docs.cryptlex.com/node-locked-licenses/using-lexactivator/using-lexactivator-with-node.js

0
adnan kamili