LoginSignup
21
30

More than 5 years have passed since last update.

【Django】APIのキーなどを本番環境では環境変数で、開発環境ではファイルで管理する

Posted at

はじめに

LINE Messaging APIなど、APIを利用したDjangoアプリを個人開発する際、APIのキー情報を

  • Herokuなどの本番環境では環境変数に設定
  • ローカルの開発環境ではlocal_settings.pyに直書き

して管理する方法を採ったので、その方法をまとめます。

そのような管理にした理由

  • GitHubで公開するソースコード(local_settings.py以外)では、APIのキーを秘匿したい

  • 開発環境であるMacではAPI利用アプリを複数開発するので、APIのキーを環境変数ではなく、Djangoプロジェクト単位のファイル(local_settings.py)で管理したい

  • views.pyやmodels.pyなどではAPIのキーをどこから読み込んでいるか意識させない作りにしたい(本番環境と開発環境でロジックに差をつけたくない)

為です。

環境

  • Python 3.6.6
  • Django 2.1.5

settings.pyとlocal_settings.pyでのAPIキーの設定方法

local_settings.pyでは、DEBUG = Trueにしつつ、各APIのキーを直書きします。

local_settings.py
# ...

DEBUG = True

SECRET_KEY = 'hogehogehoge...'

LINE_CHANNEL_ACCESS_TOKEN = 'hogehogehoge...' 
LINE_CHANNEL_SECRET = 'hogehogehoge...'

settings.pyでは、DEBUG = Falseにした上で、local_settings.pyを読みに行かせ、local_settings.pyの存在しない本番環境であれば(DEBUG = Trueにならなければ)、各APIキーを本番環境の環境変数から読み込みます。

settings.py
# ...

DEBUG = False

# ...

try:
    from .local_settings import *
except ImportError:
    pass

if not DEBUG:
    SECRET_KEY = os.environ['SECRET_KEY']
    LINE_CHANNEL_ACCESS_TOKEN = os.environ['LINE_CHANNEL_ACCESS_TOKEN']
    LINE_CHANNEL_SECRET = os.environ['LINE_CHANNEL_SECRET']

views.pyやmodels.pyなどで、APIのキーを使う

settings.py(local_settings.py)で設定した変数は、

from django.conf import settings
print(settings.LINE_CHANNEL_ACCESS_TOKEN)

とすることで、views.pyやmodels.pyなどから参照することができます。

以下はviews.pyにおいて、LINE Messaging APIのキーを使用している例です。

APIのキーを環境変数から読むのかファイルから読むのか、はsettings.py側で制御しているので、views.py側では意識する必要がなくなりました。

view.py
from django.http import HttpResponse, HttpResponseForbidden
from django.views.decorators.csrf import csrf_exempt
from django.conf import settings
from linebot import LineBotApi, WebhookHandler
from linebot.exceptions import InvalidSignatureError
from linebot.models import (
    MessageEvent,
    TextMessage,
    TextSendMessage
)

# settings.pyに設定したAPIキーを参照
line_bot_api = LineBotApi(channel_access_token=settings.LINE_CHANNEL_ACCESS_TOKEN)
handler = WebhookHandler(channel_secret=settings.LINE_CHANNEL_SECRET)


@csrf_exempt
def callback(request):
    signature = request.META['HTTP_X_LINE_SIGNATURE']
    body = request.body.decode('utf-8')
    try:
        handler.handle(body, signature)
    except InvalidSignatureError:
        return HttpResponseForbidden()
    return HttpResponse('OK', status=200)

# ...

参考

21
30
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
21
30