在 Go 中处理纯文本密码的最佳方法是什么
What is the best way to deal with plain text passwords in Go
我正在创建一个简单的程序来在我的 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
}
那么我该如何对这个程序进行user/pass的输入呢?我会让这个项目 'Public' 在 Github.
我正在考虑创建一个类似“input”的文件并将其添加到 .gitignore。
因此,如果其他人想使用该程序,该人只需要创建自己的“输入”文件,程序就会从中读取。
你怎么看?
将并非对每个人都适用的配置数据放入环境变量。
使用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/Whosebug/tree/main/69335827
我正在创建一个简单的程序来在我的 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
}
那么我该如何对这个程序进行user/pass的输入呢?我会让这个项目 'Public' 在 Github.
我正在考虑创建一个类似“input”的文件并将其添加到 .gitignore。 因此,如果其他人想使用该程序,该人只需要创建自己的“输入”文件,程序就会从中读取。
你怎么看?
将并非对每个人都适用的配置数据放入环境变量。
使用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/Whosebug/tree/main/69335827