バックエンドを開発していると、秘密にしたい値がどうしてもでてきますよね。
AWSのシークレットキー・APIキー・DBの接続情報等…
ただ、それをsettings.pyでハードコードしてGitで管理というのは楽ですが正直セキュリティ的によろしくありません。
となると、「環境変数で管理しよう」となってくる事が多いと思いますが、
単純に環境変数にすると開発環境での管理が面倒になる場合もあります。
とりあえず環境変数にした場合の罠
開発環境はMac。
IDEはPythonista御用達のPyCharmを使います。
環境変数設定ファイルを作成
# MySQL
DB_NAME=db_name
DB_PASSWORD=hogepass
DB_USER=hogehoge
DB_HOST=127.0.0.1
DB_PORT=3306
DB_ENGINE=django.db.backends.mysql
# AWS Settings
DJANGO_AWS_S3_BUCKET_NAME=huga-storage
DJANGO_AWS_ACCESS_KEY=xxxxxxxxxxxxxxxxxx
DJANGO_AWS_SECRET_KEY=xxxxxxxxxxxxxxxxxx
settings.pyを編集
import os
BASE_DIR = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
・・・
AWS_S3_BUCKET_NAME=os.environ['DJANGO_AWS_S3_BUCKET_NAME']
AWS_ACCESS_KEY=os.environ['DJANGO_AWS_ACCESS_KEY']
AWS_SECRET_KEY=os.environ['DJANGO_AWS_SECRET_KEY']
DATABASES = {
'default': {
'ENGINE': os.environ['POSTGRES_ENGINE'],
'NAME': os.environ['POSTGRES_NAME'],
'USER': os.environ['POSTGRES_USER'],
'PASSWORD': os.environ['POSTGRES_PASSWORD'],
'HOST': os.environ['POSTGRES_HOST'],
'PORT': os.environ['POSTGRES_PORT'],
}
}
・・・
と、こんな感じでしょうか。
問題点
- コマンドラインから行う時はMacの環境変数にセットしなければならない。
- Macの環境変数にセットしてなかったらPycharm
Run/Debug Configrations
で環境変数をいちいち指定しないといけない。
たかが2点されど2点。
まずLinux運用想定で.envを作成したとしても、Macだとexport
しないと環境変数に登録できないし…
↓のようなシェルスクリプト作成して環境変数修正するたびに実行してなんてしたくない。
#!/bin/sh
# ファイルを1行ずつ読み込んで表示
TESTFILE=./.env
while read line; do
export $line
done < $TESTFILE
という事で、こんな無駄をなくしましょう。
django-environを使用する
Github
https://github.com/joke2k/django-environ
ありがたや(-人-)
導入
$ pip install django-environ
環境変数設定ファイルを修正
# MySQL
DATABASE_URL=mysql://hogehoge:hogepass@127.0.0.1:3306/db_name
# AWS Settings
DJANGO_AWS_S3_BUCKET_NAME=huga-storage
DJANGO_AWS_ACCESS_KEY=xxxxxxxxxxxxxxxxxx
DJANGO_AWS_SECRET_KEY=xxxxxxxxxxxxxxxxxx
settings.pyを改善
import environ
# settings.pyの位置を起点として3つ上の親ディレクトリを参照。
BASE_DIR = environ.Path(__file__) - 3
env = environ.Env()
# 環境変数でDJANGO_READ_ENV_FILEをTrueにしておくと.envを読んでくれる。
READ_ENV_FILE = env.bool('DJANGO_READ_ENV_FILE', default=False)
if READ_ENV_FILE:
env_file = str(BASE_DIR.path('.env'))
env.read_env(env_file)
・・・
AWS_S3_BUCKET_NAME=env('DJANGO_AWS_S3_BUCKET_NAME')
AWS_ACCESS_KEY=env('DJANGO_AWS_ACCESS_KEY')
AWS_SECRET_KEY=env('DJANGO_AWS_SECRET_KEY')
DATABASES = {
'default': env.db() # デフォルトでDATABASE_URLの環境変数を分解してくれる
}
・・・
ポイント
- Macに環境変数を設定しなくても、1つ環境変数をTrueにしておけば
.env
を読んでくれる。 - DATABASE_URLという環境変数で一行書くことでDBの定義ができる
- ディレクトリのベースディレクトリ定義などがスッキリする。
ちなみに、DB以外にもキャッシュとかもワンラインで定義できます。
DJANGO_READ_ENV_FILE
をTrueにしておけば.env
を修正しても毎回読み直してくれるのでかなり便利です。
まとめ
使用したメソッドは一例ですが、これだけでもスッキリしたコードになりました。
環境変数にする事によりセキュリティ対策にもなるし、開発と本番とかでsettingsファイルを切り替える必要もなくなります。
OSSは日に日に追加・改善等が進められているので、いつのまにか痒い所に手が届くライブラリが作成されているという事が無いようにしていく事が大切ですね。
そして人様が開発したライブラリに頼りきるのではなく、自らも積極的にOSSに貢献していきましょう!
Let's OSS Life!!!