質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Heroku

HerokuはHeroku社が開発と運営を行っているPaaSの名称です。RubyやNode.js、Python、そしてJVMベース(Java、Scala、Clojureなど)の複数のプログラミング言語をサポートしている。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

3回答

1805閲覧

Node.js + HerokuでAPIKeyを隠匿したい

退会済みユーザー

退会済みユーザー

総合スコア0

Heroku

HerokuはHeroku社が開発と運営を行っているPaaSの名称です。RubyやNode.js、Python、そしてJVMベース(Java、Scala、Clojureなど)の複数のプログラミング言語をサポートしている。

Node.js

Node.jsとはGoogleのV8 JavaScriptエンジンを使用しているサーバーサイドのイベント駆動型プログラムです。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

0クリップ

投稿2019/07/04 02:55

編集2019/07/04 07:58

HTML + CSS + JSでAPIを使って画像を取得し、表示しているのですが、
JSではAPIKeyがJSファイル上に載ってしまっていてよろしくないので隠匿する方法を探しています。
いろいろ確認していたところ、.env ファイルを作って.gitignoreに入れればよいという書き込みも見つけたのですが、GitHub上に.envファイルが無いと結果読み込まれないため実用性がなく、誤って公開するリスクも有るとのことで、Keyは1つなのでファイルにしない別の方法を探していたところ、
herokuに公開し、Herokuの環境変数に入れてそれを取り出す方法をみつけ試しています。
以下の通り、ひとまずHerokuの環境変数に入れることは完了している状況です。

heroku config

=== sample-app Config Vars
key_test: test

環境変数には登録されているようなのですが、
App.js上に以下のように記載したところ、登録がないと怒られます。

{console.log(JSON.stringify(process.env.key_test))}

なお、以下も試したのですが、一覧を表示しても一覧に出ない状況でした。

{console.log(JSON.stringify(process.env))}

(Console.log(process.env)ではデータが受け取れなかったので探したところ上記で動くことがわかりました)

console

1 {"NODE_ENV":"development","PUBLIC_URL":""}

developmentで設定していない(特に指定はしていない)のですが、どこかで入力が足りていないのでしょうか?
dotenv.jsの導入も検討しましたが、グループ開発で行っており、他のメンバーはNode.jsをローカルに入れていないため、最小限の構成で動くものを作りたい(Herokuの環境変数を読み込むだけなら別のJSファイルも不要なのでメンバーへの影響もあまりない)と考えています。

お手数ですが確認よろしくお願いいたします。
また、他に情報が必要でしたらお知らせください。

追記:
以下について、追記していただいた通りReactで作ったテスト(本来テスト環境ではないですがConsoleにテストデータを投げるために利用)です。ややこしくなって申し訳ないです。

> heroku config === sample-app Config Vars key_test: test 環境変数には登録されているようなのですが、 App.js上に以下のように記載したところ、登録がないと怒られます。 > {console.log(JSON.stringify(process.env.key_test))} なお、以下も試したのですが、一覧を表示しても一覧に出ない状況でした。 > {console.log(JSON.stringify(process.env))} (Console.log(process.env)ではデータが受け取れなかったので探したところ上記で動くことがわかりました)

エラーは「undefined」ですが、それは「process.env」の中に「key_test」がないということだと理解してます(環境変数を受け取れない仕様ならprocess.envでデータが受け取れないはずですよね。)
ちなみにConsoleを開いてConsole.log(process.env)を後から取得しようとしても

Uncaught ReferenceError: process is not defined

at <anonymous>:1:1

と出ますので開いた後は任意のユーザーがprocess.envにアクセス出来ないようになっている、という認識でいました。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/07/04 03:03

クライアントサイドJSかサーバーサイドJSどちらの話をしていますか?
退会済みユーザー

退会済みユーザー

2019/07/04 03:20 編集

書いているコードはクライアントサイドJS(何もインストールしていないJS[JS5?])です。 残りのメンバーはNode.jsを入れる知識がないので、私がHerokuを立ててGitHubと紐づけ、GitHubへのPushでHerokuもアップデートされるように設定をしてあります。 希望としてはHerokuの環境変数に設定したデータを他者が読み込めない状態で、JSファイルの変数にAPIKeyを渡したいと考えてます。 Heroku+Node.jsで環境変数に設定をするところまでは情報が出ているのですが、 Keyの取得(確認)では多くがconsole.log(process.env.KEY)で取得できるように書いていますが取得できずでした・・・ JSON.stringify(process.env.key_test)を利用してもKeyの設定がないものが出てきているのでどこかがおかしいのだと思うのですが。。。
退会済みユーザー

退会済みユーザー

2019/07/04 04:01

クライアントJSでは環境変数の読み込みはできないですがそこは大丈夫ですか?
退会済みユーザー

退会済みユーザー

2019/07/04 06:36 編集

大丈夫です。 HerokuでWeb公開する際Node.js(サーバーサイド)で公開されているはずなので、それを利用して環境変数から取得して、それを素のJSで受け取ろうととしているという意味です。 記載している通り、テスト環境ではJSON.stringify(process.env)でデータは取得できているのでセキュリティで弾かれている問題ではないはずなのですが、取得しているデータはエラーということなんでしょうか?
退会済みユーザー

退会済みユーザー

2019/07/04 05:07

素のJSとはなんですか?
退会済みユーザー

退会済みユーザー

2019/07/04 06:19

申し訳ないのですが質問がこちらの疑問点の趣旨と外れてしまっている気がします。 一応回答しますと素のJSはNode.jsなどを利用しない(何も入っていない)JavaScriptという意味です。 言葉が足りないようなので追記しますと ・Local:HTML/CSS/JS(Node.jsなどを利用しない、素のJS) ・Heroku:上記+Herokuの環境(ビルド時にNode.jsが自動で入るという理解です) で、HerokuにはいっているNode.jsでHerokuに設定したAPIKey(環境変数)を取得して利用する(Function内でLocal変数を作成して当てることで完結させればユーザーはデータを取得できない) というのがやりたいことです。 https://numb86-tech.hatenablog.com/entry/2017/01/24/000940 https://mhaya18.hatenablog.com/entry/2018/08/24/164301 https://garafu.blogspot.com/2017/05/node-environment-variables.html 上記などを読むと、  ・基本的にAPIKeyは公開すべきではない  ・環境変数にKeyを入れて運用するのがよい  ・環境変数の取得は可能 というように記載されているように読めますが、違うのでしょうか・・・? 意図としては最小構成(インストールの不要な環境がベスト)でAPIキーを隠せればいいので、 利用できないようであれば何を入れれば利用可能か情報をいただけると助かります。
退会済みユーザー

退会済みユーザー

2019/07/04 06:47

素のJSという言葉は私からすると「フレームワークやライブラリを使わないプレーンなJS」という意味に思えます。 なので上を満たしていればサーバーサイドJSも素のJSと思っています。 曖昧な表現は誤解を招くので「クライアントサイド(フロントエンド)JS」「サーバーサイドJS(Node.js)」と表現して頂いた方がいいと思います。
退会済みユーザー

退会済みユーザー

2019/07/04 07:22

「素のJS」という表現はインターネット上で記載されていた方法をそのままトレースしたのですが・・・ https://qiita.com/bsken315/items/fd3f4b8973e66b6405d5 https://www.webopixel.net/javascript/1516.html https://teratail.com/questions/95230 ざっとみるだけでこれだけあった(もっとありましたが)ので「素のJS(JavaScript)」という表現は一般的なものという認識でいました。誤解を招く表現なのですね。気をつけます。 なお、先程コメントさせていただいたように 「最小構成(インストールの不要な環境がベスト)でAPIキーを隠せればいい」 のですが、どういった構成であれば対応可能でしょうか? > (Function内でLocal変数を作成して当てることで完結させればユーザーはデータを取得できない) こちらについては方法としてざっくり想定していたやり方ですがとくにこだわりはないです。Keyを隠せればいいので。(ローカル変数にアクセスする方法があるというのがびっくりでした。まだ駆け出しなものでいろいろわからず申し訳ないです) Node.jsはHerokuでビルドする際に自動で入るものではないのでしょうか? (Package.jsonの設定などで入らないということであれば自動で入る方法を知りたいです。) できれば回答いただけますと幸いです。
退会済みユーザー

退会済みユーザー

2019/07/04 07:34 編集

記事読みましたがやはり「ライブラリ(もっというとjQuery)を使わないJS」という意味で使われていると思います。 (クライアントサイドの)素のJS (サーバーサイドの)素のJS 両方有り得ます。 今回はカッコの内容が大事なので述べました。
退会済みユーザー

退会済みユーザー

2019/07/04 07:50

> Node.jsはHerokuでビルドする際に自動で入るものではないのでしょうか? Node.jsとは要するにサーバーサイドJSのことです。 なのでAPI KEYを使う処理はサーバーサイドで行う必要があります。 必要な情報を取得したらJSON APIなどでやり取りしてクライアントサイド側に渡します。
退会済みユーザー

退会済みユーザー

2019/07/04 07:57

今後私への返事は回答にコメントして頂ければと思います。
guest

回答3

0

クライアントサイドJSでは環境変数の読み込みはできないですがそこは大丈夫ですか?

クライアントサイドJSは 閲覧者のブラウザ で動作しますから、Herokuサーバの環境変数は読み取れません。

そもそも process.env 自体が使えないはずです。

追記

サーバーサイドからクライアントサイドにAPIKEYを渡しても閲覧者から見えます。
APIKEYをクライアントサイドで使ってはいけません。

追記2

上記などを読むと、
・基本的にAPIKeyは公開すべきではない
・環境変数にKeyを入れて運用するのがよい
・環境変数の取得は可能
というように記載されているように読めますが、違うのでしょうか・・・?

合っています。
ただしすべて サーバーサイド 環境であることが前提です。
上げて頂いた記事もすべてサーバーサイド前提で書かれていますよ。

(Function内でLocal変数を作成して当てることで完結させればユーザーはデータを取得できない)

意味がわからなかったのですが、 コードを工夫すればクライアントサイドでキーを扱っても良い と思っているのであればそれは間違いです。
クライアントサイドで機密情報を扱うのはやめましょう。

例えば質問箱というサービスはクライアントサイドにトークンを持ってきたせいで流出し問題となりました。

https://www.itmedia.co.jp/news/articles/1901/29/news117.html

環境変数に埋めたAPIキーを使うのであれば サーバーサイド で行って下さい。
サーバ側でAPIキーを使って必要な情報を取得し、クライアント側に送ってもいい情報だけを返すのが一般的な実装です。

追記3

どうにも噛み合ってない感じがあるので、

App.js上に以下のように記載したところ、登録がないと怒られます。

この際の具体的なエラーメッセージを共有して頂いた方が良さそうです。

App.js っておそらくReactコンポーネントか何かだと思うので、それはクライアントサイドになりますからそこでは環境変数は取得できないという話をしているのですが・・・)

追記4

ローカル変数にアクセスする方法があるというのがびっくりでした。まだ駆け出しなものでいろいろわからず申し訳ないです

クライアント側のソースコードは閲覧者に丸見えですからいくらでもデバッグ可能です。

どういった構成であれば対応可能でしょうか?

私ならサーバを立ててそこでAPIキーを使う処理を行います。
その処理で得られた情報をJSON API越しでクライアントに渡します。

サーバの言語はPHP, Rubyなど色々選択肢はありますがNode.jsが良いならそれでも構いません。

追記5

Uncaught ReferenceError: process is not defined
つまり processは定義されていない というエラーです。

そもそも process.env 自体が使えないはずです。

と先程から言っているようにクライアントサイドでは process はそもそも無いです。
繰り返しになりますがサーバにセットした環境変数はサーバ内でしか取得できません。

質問者さんはクライアントとサーバの違いを勉強された方が良い気がしています。

追記6

どうにもクライアントサイドで動作する App.js の中で環境変数が取得できると思い込んでいるようですが、
では聞きますが、Herokuの環境変数に NODE_ENVPUBLIC_URL は存在しますか?

heroku config === sample-app Config Vars key_test: test

質問者さんが提示されている通り存在しないはずです。
明らかにprocess.envで取得できる値とherokuにセットしている環境変数に矛盾が生じています。

何度も言いますが App.js の中でHerokuの環境変数は取得できないです。
また、APIキーをクライアントサイドで扱うべきではないです。

追記7

気が向いたのでがんばって作りました。
そろそろベストアンサーにして欲しい気持ちです。

図

①クライアントからサーバのAPIを叩きます
②サーバから外部サービスのAPIを叩きます(ここでキーが必要になるはず)
③外部サービスから欲しい情報が返ってきます
④③で得た情報をクライアントに返します

サーバは

  • PHP Laravel
  • Ruby Rails
  • Python Django
  • Node.js Express

など色々選択肢があります。
上の図ではなんとなくRailsにしています。

APIキーのような機密情報はサーバに持たせます。
クライアントサイドで扱うのは何度も言っている通り危険です。

Node.jsでやる場合はExpressというフレームワークが一番有名です。

サーバについて知識がなければ1から勉強してください。

私から示せる 最小限の手順 は上記になります。
下の記事のようにキーを適当に扱って抜かれると大変なことになりますから、十分な知識を持って取り組んでください。

https://qiita.com/AkiyoshiOkano/items/72002409e3be9215ae7e

素直にメンバーにNPMを入れてもらうよう交渉したほうがいいんでしょうか・・・?

必要なら入れるのが大前提としか言えません。

投稿2019/07/04 04:03

編集2019/07/04 12:03
退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/07/04 08:22

だいぶ噛み合っていないような気がしていますが、 ・Local:HTML/CSS/JS(Node.jsなどを利用しない、素のJS) ・Heroku:上記+Herokuの環境(ビルド時にNode.jsが自動で入るという理解です) で、HerokuにはいっているNode.jsでHerokuに設定したAPIKey(環境変数)を取得して利用する 予定なので、タイトルにもある通り(Herokuに入っている)「Node.js + HerokuでAPIKeyを隠匿したい」んです。方法は特にこだわっていません(フロントエンドJSである必要はありません) >Node.jsはHerokuでビルドする際に自動で入るものではないのでしょうか? Local環境で揃えていなければ自動で入ることはないのか、という質問についてはいかがでしょうか・・・? 追記5について: {console.log(JSON.stringify(process.env))} の値がConsole.logに以下のように表示される、と一番最初に記載しているのですが・・・ >{"NODE_ENV":"development","PUBLIC_URL":""} なので、 1.App.js内の{console.log(JSON.stringify(process.env))} →値取得可能。つまり「Process.env」を取得できている 2. ブラウザのConsoleを開いてConsole.log(process.env)を打つ →値取得不可。「Process」がないと出る で、私の質問は2ではなく1で、私がHeroku configに設定した環境変数が表示されない、という質問なので、クライアントサイド・サーバーサイドかどうかについては論点がずれているように思います。
退会済みユーザー

退会済みユーザー

2019/07/04 08:26

もしかしてcreate-react-appを使ってますか? create-react-appの場合は確かにprocess.env.XXXXXが使えるようです。 ただし(詳細な実装はしりませんが)擬似的に.envを使えるようにしただけで本当に環境変数が読めるわけではないです。 また、クライアントサイドで機密を扱うことのリスクも回避できません。
退会済みユーザー

退会済みユーザー

2019/07/04 08:28

> Local環境で揃えていなければ自動で入ることはないのか、という質問についてはいかがでしょうか・・・? 質問の意味をよくわかっていないかもしれませんが、 とりあえずherokuでnode.jsを使う場合はpackage.jsonとpackage-lock.jsonが必要です。
退会済みユーザー

退会済みユーザー

2019/07/04 08:45

> クライアントサイド・サーバーサイドかどうかについては論点がずれているように思います。 ずれていないです。 質問者さんの中でJSがブラウザで動作するのか、サーバで動作するのか曖昧な理解になっていることが今一番問題だと思います。
退会済みユーザー

退会済みユーザー

2019/07/04 10:27 編集

根気強くコメントしていただきありがとうございます。 >create-react-appの場合は確かにprocess.env.XXXXXが使えるようです。 >ただし(詳細な実装はしりませんが)擬似的に.envを使えるようにしただけで本当に環境変数が読めるわけではないです。 これは知りませんでした。テストしている環境では使ってます。 フロントエンドのファイルとして読み込まれている(?)App.jsでProcessが拾える理由はその点にあるということですね。ありがととうございます。 そうなると >2. ブラウザのConsoleを開いてConsole.log(process.env)を打つ これでなぜ値が取得できなくなっているかが疑問ですが・・・(素人考えだと値をフロントエンドJSに渡しているのであれば表示できるのが普通=打ったコマンドについてはバックエンドJSとして動いている、のかなと思っていましたが)おそらく擬似的な値は起動時のみなんでしょうね。 サーバーサイドのJS用のJSファイルって作れるんでしょうか?そしてそれを.gitignoreしてもきちんと読み込まれるんでしょうか? 他に方法を考えるとPackage.jsonへ追記くらいしか正直方法が浮かばないのですが(それもやり方はまだわかりませんが)、検索しようにも 「console.log(process.env)でコンソールに表示ができる」 といったような話しか見つからず、実装する方法がわからないため困っています。 素直にメンバーにNPMを入れてもらうよう交渉したほうがいいんでしょうか・・・?
退会済みユーザー

退会済みユーザー

2019/07/04 12:33 編集

> これでなぜ値が取得できなくなっているかが疑問ですが・・・(素人考えだと値をフロントエンドJSに渡しているのであれば表示できるのが普通=打ったコマンドについてはバックエンドJSとして動いている、のかなと思っていましたが)おそらく擬似的な値は起動時のみなんでしょうね。 ビルドする過程でできるようになっているだけです。 あと何度も言っていますがブラウザのコンソールはクライアントサイドJSです。 > サーバーサイドのJS用のJSファイルって作れるんでしょうか?そしてそれを.gitignoreしてもきちんと読み込まれるんでしょうか? なぜサーバーサイドのファイルを.gitignoreに入れるのかさっぱりわからないです・・・ ignoreすべきは環境変数の値だけのはずです。 あとはサーバアプリケーションの作り方を一度学んでくださいとしか言えないですね。
_osd

2021/08/23 06:55

nuxt触ってみている初心者なのですが,とても参考になりました. テキストで残しておいていただいてありがとうございます!
guest

0

ベストアンサー

API keyのいらないAPIを使って解決しました。
バックエンドのJSのどこにどう書くのか、いまいちわかりませんでしたが回答頂いた方はありがとうございました。

投稿2019/07/11 08:51

退会済みユーザー

退会済みユーザー

総合スコア0

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2019/07/15 13:33

何度も言いますが一から勉強して下さい。
guest

0

App.js上に以下のように記載したところ、登録がないと怒られます。

このApp.jsクライアントサイドのものの場合、process.envをコードで使っているとそれはビルド時にクライアント側のコードに値が埋め込まれます。

つまり、ここにどうにかしてAPIキーを入れたとすると、それも含まれたJavaScriptファイルが出来上がってしまいます。キーの漏洩になるので、取ってはいけない手法です。

投稿2019/07/04 08:29

maisumakun

総合スコア145121

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問