【问题标题】:Storing the secrets (passwords) in a separate file将机密(密码)存储在单独的文件中
【发布时间】:2014-10-19 12:26:03
【问题描述】:

为 Python 脚本存储应用程序机密(密码、访问令牌)的最简单方法是什么?我以为它会像 Ruby 中的 *.yml 文件,但令人惊讶的是,我发现事实并非如此。那么它是什么呢?最简单的解决方案是什么?

我想将它们放在一个单独的文件中,因为这样我将不能将该文件推送到 github 存储库。

【问题讨论】:

标签: python configuration settings


【解决方案1】:

我个人更喜欢使用 yaml 文件和 pyyaml 库。 此处的文档:https://pyyaml.org/wiki/PyYAMLDocumentation

创建.gitignore 规则非常快速且轻松,出错的可能性为零。您可以在类似 Linux / UNIX 的系统上使用 echo 添加规则:

echo -e '*.yaml\n*.yml' >> .gitignore

以下是从阅读器的同一文件夹/位置中的设置 .yaml 文件中检索设置的示例。

代码片段:

#!/usr/bin/env python3

import yaml
from pathlib import Path


def get_settings():
    full_file_path = Path(__file__).parent.joinpath('settings.yaml')
    with open(full_file_path) as settings:
        settings_data = yaml.load(settings, Loader=yaml.Loader)
    return settings_data

【讨论】:

【解决方案2】:

我正在处理完全相同的问题,实际上最终得到了与 kecer 建议的相同的解决方案。因为我需要在几十个脚本中使用它,所以我创建了自己的库。让我与您分享这个解决方案。

credlib.py -- 处理凭据的通用库

class credential:
    def __init__(self, hostname, username, password):
        self.hostname = hostname
        self.username = username
        self.password = password

mycredentials.py -- 用于存储所有凭据的本地文件

from credlib import credential
sys_prod = credential("srv01", "user", "pass")
sys_stg = credential("srv02", "user", "pass")
sys_db = credential("db01", "userdb", "passdb")

mysystemlib.py -- 这是访问我的系统的通用库(支持新的凭证系统和旧的凭证系统)

from credlib import credential

def system_login(*args): # this is new function definition
#def system_login(hostname, username, password): # this was previous function definition

    if len(args) == 1 and isinstance(args[0], credential):
        hostname = args[0].hostname
        username = args[0].username
        password = args[0].password
    elif len(args) == 3:
        hostname = args[0]
        username = args[1]
        password = args[2]
    else:
        raise ValueError('Invalid arguments')

    do_login(hostname, username, password) # this is original system login call

ma​​in.py -- 结合凭据和系统库的主脚本

from mycredentials import sys_stg, sys_db
import mysystemlib
...
mysystemlib.system_login(sys_stg)

请注意,旧的主机名/用户名/密码方式仍然有效,因此不会影响旧脚本:

mysystemlib.system_login("srv02", "user", "pass")

这有很多好处:

  • 我们所有的 python 脚本都使用相同的凭据系统
  • 有密码的文件是分开的(文件可以有更严格的权限)
  • 文件不存储在我们的 git 存储库中(通过 .gitignore 排除),因此我们的 python 脚本/库可以在不暴露凭据的情况下与其他人共享(每个人都在本地文件中定义自己的凭据)
  • 如果需要更改密码,我们只在一个地方进行

【讨论】:

  • 什么是 .gitignore 规则以确保它不会被错误地推送到公共仓库!
  • 在我们的例子中,我们的经验法则是将所有凭证文件命名为“cred_*.py”,所以这就是我们在 .gitignore 中的内容。当然,这并不能防止人为错误地保存具有不同名称的凭证文件。不过,我们从来没有遇到过这个问题。对我们来说最重要的是在单独的文件中分离代码和凭据。
【解决方案3】:

我认为将凭据存储在另一个 *py 文件中是您最安全的选择。然后只需导入它。示例如下所示

config.py

username = "xy"
password = "abcd"

main.py

import config
login(config.username, config.password)

【讨论】:

  • 其实我也想写点东西,要么在这个文件里,要么在另一个文件里。
  • 请注意,config.py 中的任意代码都会被执行。这是一个问题,尤其是如果 main.py 在与 config.py 不同的信任区域中运行。
  • 另外,在凭证文件上使用 *py 文件扩展名会使其更有可能被错误地推送到 gh 存储库!
  • @Jonathan 在这种情况下,config 中的所有代码仍在运行。因此,如果您不信任config.py,那仍然是有风险的。如果您不像应用程序代码那样信任config.py,那么无论您如何调整它,这都是一种危险的方法。
  • @jtpereyda 谢谢 - 我今天学到了一些东西。保持安全...
猜你喜欢
  • 2016-09-06
  • 2019-06-19
  • 1970-01-01
  • 1970-01-01
  • 2022-01-18
  • 1970-01-01
  • 2020-06-16
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多