Node.js 環境変数の設定

こんにちは、皆さん!
今回はNode.jsで安全に環境変数を設定する方法について紹介していきたいと思います。


  • トピック:
  1. 環境変数とは?
  2. なぜ環境変数を使うのか?
  3. なぜ環境変数を安全に保護しないといけないのか?
  4. どうやって安全にキープするのか?
  5. では、試してみましょう!!


環境変数とは?

***環境変数の基本を飛ばしたい方はこちら!***
簡単に言いますと、外部から与えられるデータのことです。直接コードの中ではそのものを書かずに他のファイルからそれを読み取ります。


なぜ環境変数を使うのか?

Google Mapをアプリケーションに応用しようと思ったときにAPIというものが必要になってきます。相手側のサービスを利用するにあたっての個人のIDみたいなものです。権利書みたいでもあり、そのAPIがないと利用できません。

なぜ環境変数を安全に保護しないといけないのか?

ウェブ上のコードというのはとても簡単に他人に見られます。先ほどのAPIというのはいうと、数字とアルファベットの羅列です。だから、見られたらそのまま盗まれます。そして、あなたの名義でその権利書を使い、その人のアプリケーションを作る。料金のかかるAPIですと、他人のために金を払うことになります。だから、環境変数にその危ない部分を移し、なおかつその環境変数を含んだファイルを見られないようにすることが大事なのです。


どうやって安全にキープするのか?

まず、Node.jsでは下記のように環境変数にアクセスできます。

process.env.API_KEY

envの後に環境変数の名前をつければアクセスできます。
ローカルでは他のファイルに保存しておけば、アクセスできます。このファイルに関してはgitignoreしっかりとオンラインにシェアされないように
プロダクション、つまり、オンラインでは例えば、Herokuならconfig環境変数を保存すれば他人には見られないので安全にキープできます。

では、試してみましょう!!

僕のコードをhttps://github.com/Eric1015/node-environment-variables-exampleに載せておきましたので、参考にしてください。
おススメはそのコードをダウンロードして、この記事通りに見て、そして、ローカルやHerokuで試してみることです。
まず、コードの構造について少し説明します。configディレクトリーの中にあるのが環境変数を管理する部分です。
prod.jsがプロダクション、test.jsがテスト、dev.jsがローカルという形でそれぞれがそれぞれの環境の変数を管理しています。
次にindex.jsファイルで環境に応じてどのファイルのデータを返すかを決めます。

if (process.env.NODE_ENV === 'production') {
    module.exports = require('./prod');
} else if (process.env.NODE_ENV === 'test') {
    module.exports = require('./test');
} else {
    module.exports = require('./dev');
}

ここにあるように環境ごとにそれぞれの変数を管理しているファイルを返すのです。
あとは.gitignoreの方でローカルとテスト環境の変数が外部に漏れないようにフィルターするだけ

# モジュールはわざわざプッシュする必要はない
node_modules

# ローカルとテスト環境の環境変数はGithubに表示されないようにします
config/dev.js
config/test.js



以上で環境変数の設定は完了。そしたら、server.jsで実際にどう使うかを見てみましょう!
ここではMongooseを使う際のURLを環境変数を使い、各環境で違うデータベースにアクセスできるようにします。
まず、ローカルとテスト環境のデータベースのURLを設定します。

// dev.js
module.exports = {
    DB_URI: "mongodb://localhost:27017/environment-variables-app"
}
//test.js
module.exports = {
    DB_URI: "mongodb://localhost:27017/environment-variables-app-test"
}

次にプロダクションの方の変数も定義したいのですが、プロダクションではサーバー側の設定から環境変数がパスされてきます。例えば、Herokuでこのアプリケーションを使うのなら、そこで、変数の名前をDB_URIとし、実際のURLを入れ、下記のようにその変数にアクセスします。

// prod.js
module.exports = {
    DB_URI: process.env.DB_URI
}

これならGithubに載せても他人から情報を盗まれませんね!
では、いよいよserver.js内のコードを見ていきましょう!
まず、外部から必要なものをインポートしてきます。このとき、require('./config')となっていてディレクトリーをインポートしようとしているように見えるが、実はindex.jsを認識して、そこにたどり着いているのです。
次にconst url = config.DB_URI;環境変数にアクセスし、MongoDBのURLを取得します。
そして、最後にサーバーをスタートします。

const express = require('express');
const mongoose = require('mongoose');
const config = require('./config');

const url = config.DB_URI;
const port = process.env.PORT || 8080;

// MongoDBデータベースに接続
mongoose.connect(url, function (err, res) {
    if (err) { 
      console.log ('ERROR connecting to: ' + url + '. ' + err);
    } else {
      console.log ('Succeeded connected to: ' + url);
    }
});

// サーバーをスタートする
const app = express();

app.get('/', (req, res) => res.send('Hello World!'))

app.listen(port, () => console.log(`Example app listening on port ${port}!`))



実際にこのサーバーをスタートすれば、コンソールで実際にどのMongoDBのサーバーに接続したかが見れます。


では、次はHerokuでどうやって設定するかです。
まずはHerokuのconfigを確認してみましょう!

$ heroku config

すると、まだ何も入れてないので、空の状態です。
HerokuでMongoDBを使おうとすると、mLabというアドオンを入れる必要があるので、それを入れてみましょう!

f:id:Programming_Shop:20190318080104p:plain
mLabのコンソール画面(左上のロゴを参照に)


追加した後にもう一度heroku configとやると、今足したmLabのURLが見れるはずです。

MONGODB_URI: mongodb://heroku_3636wvfr:ka9cqpra6f4r8g3gfk8n2la4bs@ds255797.mlab.com:55797/heroku_3636wvfr

こんな感じで出てくるのだが、今のアプリではDB_URIという環境変数でアクセスしているので、環境変数をこの名前で新たに追加しましょう!!
下記のコマンドを入力して、configに環境変数を追加しましょう!

$ heroku config:set DB_URI=mongodb://heroku_3636wvfr:ka9cqpra6f4r8g3gfk8n2la4bs@ds255797.mlab.com:55797/heroku_3636wvfr

後ろの部分はご自身のMongoDBのURLを入れてくださいね!
ここで、またコマンドでconfigを開くと、

DB_URI:           mongodb://heroku_3636wvfr:ka9cqpra6f4r8g3gfk8n2la4bs@ds255797.mlab.com:55797/heroku_3636wvfr

この内容が追加されています。
これでHerokuのサイト上でもアクセスできるようになります!!


まとめ

今回は環境変数を有効かつ安全に使う方法について見てきました。
僕もはじめはこんなに簡単に設定できるのかと感心しました。
みなさんの役に立つことを願います!
では、また次回まで✌
記事更新はツイッターで告知するので、ツイッターの方でもフォローお願いします!
twitter.com



最新版 2019年にプログラミング始めるならJavaScript↓↓
programming-shop.hatenablog.com