為什麼要嚴格代碼和配置分離?
是以如果你的代碼放在Github這樣的外網,萬一有一天代碼不小心洩露了,你的密碼、密鑰等配置都暴露在了公網上,這是一件非常可怕的事情。
判斷應用程式是否正确地将配置與代碼分離的一種簡單方法是,你的代碼是否可以立即開源,而不必擔心暴露任何敏感資訊。
通常的做法是将應用程式的配置存儲在環境變量中,例如在指令行中添加:
export APP_PASSWORD=123456
然後你通過環境變量加載APP_PASSWORD,例如:
import os
APP_PASSWORD_ENV = os.environ.get("APP_PASSWORD")
print(APP_PASSWORD_ENV)
這樣一來,敏感資訊就不會暴露給業務代碼,同時也會最大限度地讓開發者在正式環境中暴露敏感資訊。
但是,這裡出現了将敏感資訊設定為環境變量的問題。如果這樣的資訊很多,一一設定就太麻煩了。
你肯定希望能夠将這些敏感資訊儲存在單獨的檔案中,始終與代碼分開管理。
例如,在一個flask項目中,我們将敏感資訊放在一個名為.flaskenv. 示例 flaskenv 檔案如下所示:
FLASK_DEBUG=1
FLASK_ENV=local
FLASK_USER=svc_user1
...
但是這些配置是如何加載到環境變量中的呢?你可以使用名為python-doten子產品
安裝 python-dotenv
要安裝此子產品,你可以使用pip:
$ pip install python-dotenv
Looking in indexes: https://pypi.python.org/simple
Collecting python-dotenv
Downloading python_dotenv-0.20.0-py3-none-any.whl (17 kB)
Installing collected packages: python-dotenv
Successfully installed python-dotenv-0.20.0
加載配置檔案
如果你的應用程式從環境變量中擷取配置,你必須自己設定這些環境變量。
為了幫助你解決這個問題,你可以添加Python-dotenv到你的應用程式以使其在.env檔案存在時(例如在開發中)從檔案加載配置,同時通過環境保持可配置性:
load_dotenv
from dotenv import load_dotenv
# 加載檔案
load_dotenv(".flaskenv")
import os
flask_env = os.environ.get("FLASK_ENV")
print(flask_env) # local
加載檔案後,可以通過os.environ.
預設情況下,load_dotenv不會覆寫現有的環境變量。
dotenv_values
dotenv_values 函數的工作方式或多或少與 load_dotenv 相同,隻是它不接觸環境,它隻傳回一個包含從 .env 檔案解析的值的字典。
from dotenv import dotenv_values
config = dotenv_values(".env")
# config = {"USER": "foo", "EMAIL": "[email protected]"}
如果使用 dotenv_values 函數,則可以避免導入 os 子產品。
配置檔案格式
一個示例.env檔案類似于 BASH:
# 開發設定
DOMAIN=example.org
ADMIN_EMAIL=admin@${DOMAIN}
ROOT_URL=${DOMAIN}/app
注意:如果你在值中使用變量,請確定它們用符号{}包起來,例如${DOMAIN},因為$DOMAIN未擴充的裸變量。
鍵可以不加引号或單引号。值可以不加引号、單引号或雙引号。忽略鍵、等号和值前後的空格。值後面可以跟注釋。行可以以export指令開頭,這對其解釋沒有影響。
允許的轉義序列:
- 在單引号值中:\\,\'
- 在雙引号中:\\, \', \", \a, \b, \f, \n, \r, \t,\v
配置最佳實踐
我們将使用 Flask 作為我們的示例應用程式。在flask中,python-dotenv可以無縫內建到項目中,隻要你的項目中有.envor.flaskenv檔案,就會提示你是否安裝python-dotenv:
$ flask run
* Tip: There are .env files present. Do "pip install python-dotenv" to use them.
安裝完成後python-dotenv,裡面的配置檔案會自動加載到環境變量中。
# config.py
class LocalConfig(BaseConfig):
ENV = "development"
FLASK_DEBUG = 1
# 設定資料庫 URI
SQLALCHEMY_DATABASE_URI = os.getenv("SQLALCHEMY_DATABASE_URI")
# app.py
def create_app():
app = Flask(__name__)
app.config .from_object(LocalConfig)
# view.py
def hello():
# 加載環境變量
os.environ.get("TEST_USER")
注意:你可能要添加.env到你的.gitignore.,特别是如果它包含密碼等機密。
Django
如果你是 Django 使用者,你仍然可以使用.env檔案,隻需将以下内容添加到你的settings.py檔案中:
from dotenv import load_dotenv
load_dotenv() # 從 .env 加載配置...安全警告:将生産中使用的密鑰保密!
SECRET_KEY = str(os.getenv('SECRET_KEY'))
# github 的社交身份驗證配置
SOCIAL_AUTH_GITHUB_KEY = str(os.getenv('GITHUB_KEY'))
SOCIAL_AUTH_GITHUB_SECRET = str(os.getenv('GITHUB_SECRET'))
# 社交身份驗證配置應用
SOCIAL_AUTH_GOOGLE_OAUTH2_KEY = str(os.getenv('APP_KEY'))
SOCIAL_AUTH_GOOGLE_OAUTH2_SECRET = str(os.getenv('APP_SECRET'))
如果你發現我的任何文章有幫助或有用,麻煩點贊或者轉發。 謝謝!