【问题标题】:What is the best way to deal with plain text passwords in Go在 Go 中处理纯文本密码的最佳方法是什么
【发布时间】:2021-09-26 14:22:34
【问题描述】:

我正在创建一个简单的程序,以便在我的 IP 更改时将其注册到 OpenDNS。我知道 ddclient,但我想写自己的只是为了学习。

为了能够在 OpenDNS 上执行任何操作,我必须调用指定我的用户的 URL 并通过,所以 curl 示例类似于:curl -u user:password https://updates.opendns.com/nic/update?hostname=xxxx&myip=123.123.123.123

在 Go 中我创建了以下函数:

func registerNewIpToOpenDns(ip string) (int, error) {

    openDnsURL := "https://updates.opendns.com/nic/update?hostname=xxxx&myip=" + ip
    req, err := http.NewRequest("GET", openDnsURL, nil)
    if err != nil {
        return 0, err
    }
    req.SetBasicAuth("USER", "PASS")

    resp, err := http.DefaultClient.Do(req)
    if err != nil {
        return 0, err
    }
    defer resp.Body.Close()

    return resp.StatusCode, nil
}

那么我应该如何执行用户的输入/传递给这个程序呢?我会让这个项目在 Github 上“公开”。

我正在考虑创建一个类似于“输入”的文件并将其添加到 .gitignore。 因此,如果其他人想使用该程序,则该人只需要创建自己的“输入”文件,程序就会从中读取。

你怎么看?

【问题讨论】:

    标签: go passwords


    【解决方案1】:

    将不适合所有人的配置数据放入环境变量

    使用os.Getenv() 在运行时检索变量。确保它们被设置为看起来有效的东西(至少不是空字符串)作为程序配置的一部分。

    然后,如果您从systemd 运行此配置文件,您可以在systemd 配置文件中设置环境变量,或者在.bash_config 中为专用于此进程的用户设置环境变量,或者在最方便的位置你的程序被执行了。

    或者,创建一个配置文件你可以从你的程序中读取。我通常使用 Json 编码进行这样的配置,但你可以使用任何东西。从配置文件中读取秘密可能比环境变量更安全,环境变量通常可以被系统进程自省。

    当我创建一个配置文件时,我通常用一个结构来建模我的配置,

    type Config struct {
       Username string
       Password string
    }
    

    然后作为程序初始化的一部分,我会做类似的事情

    const ConfigFileEnv "ConfigFile" // avoid typing errors 
    var config Config
    ... 
    if f, err := os.Open(os.Getenv(ConfigFileEnv); err != nil {
      panic(fmt.Errorf("Couldn't open config file %s: %w",
        os.Getenv(ConfigFileEnv),
        err,
      ))
    } else if err := json.NewDecoder(f).Decode(&config); err != nil {
       panic(fmt.Errorf("Couldn't decode json from config file %s: %w", 
          os.Getenv(ConfigFileEnv),
          err
       )
    }
    // Now config file has been loaded into config
    ...
    req.SetBasicAuth(config.Username, config.Password)
    

    工作最小示例(没有您的逻辑):https://github.com/farrellit/stackoverflow/tree/main/69335827

    【讨论】:

    • 您好丹尼尔,首先,感谢您的回答。我正在搜索并最终找到了一些解决方案,例如 godotenv 和 viper,在这种情况下,我应该使用其中一个还是您的标准库方法?为什么在这种情况下我们需要一个结构体?
    • 这完全取决于您作为实施者。如果您认为 godotenv 或 viper 的功能是可取的,请务必使用它们。至于为什么是结构体,有两个原因:第一,结构体在 Go 中与 Json 配合得很好,第二,因为任何时候我有多个一起使用的标量,我通常会使用 struct 将它们保持在一起.这更容易传递,如果我构建对结构进行操作的方法(设想使用func (c *Config)Validate() error func 来验证配置),则特别方便。
    猜你喜欢
    • 2010-09-13
    • 2011-05-20
    • 1970-01-01
    • 2023-03-06
    • 2018-12-03
    • 1970-01-01
    • 2010-09-06
    • 2011-07-16
    • 1970-01-01
    相关资源
    最近更新 更多