天天看點

Python—優雅地分離代碼和敏感資訊

作者:喜歡編碼的社畜
Python—優雅地分離代碼和敏感資訊

為什麼要嚴格代碼和配置分離?

是以如果你的代碼放在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'))           

如果你發現我的任何文章有幫助或有用,麻煩點贊或者轉發。 謝謝!