<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          如何避免將密碼提交到代碼庫(kù)了?詳解 Go 中的環(huán)境變量

          共 5900字,需瀏覽 12分鐘

           ·

          2020-12-26 15:57

          點(diǎn)擊上方藍(lán)色“Go語(yǔ)言中文網(wǎng)”關(guān)注,每天一起學(xué) Go

          了解環(huán)境變量以及在 Golang 應(yīng)用程序中使用它們的不同方法。

          開(kāi)始之前

          本教程假定你具有:

          • 對(duì) Go 語(yǔ)言的基本了解
          • 系統(tǒng)上安裝了最新 Golang 版本
          • 幾分鐘的時(shí)間

          在本文中,我們將了解環(huán)境變量以及為什么要使用它們。并且將使用內(nèi)置和第三方包在 Go 應(yīng)用程序中訪問(wèn)它們。

          什么是環(huán)境變量?

          環(huán)境變量是系統(tǒng)級(jí)的鍵-值對(duì),正在運(yùn)行的進(jìn)程可以訪問(wèn)它。這些通常用于使同一程序在不同的部署環(huán)境(例如 PROD, DEV 或 TEST)中表現(xiàn)不同。在環(huán)境中存儲(chǔ)配置是 twelve-factor 應(yīng)用程序的原理之一。它使應(yīng)用程序具有可移植性。

          為什么要使用環(huán)境變量

          • 如果您在代碼中使用敏感信息,那么所有有權(quán)訪問(wèn)該代碼的未授權(quán)用戶都將擁有敏感數(shù)據(jù),您可能不希望如此。
          • 如果您使用的代碼版本控制工具如:git,那么可能將 DB 憑據(jù)與代碼一起推送,它將公開(kāi)。
          • 如果要在一處管理變量,則可以進(jìn)行任何更改,而不必在應(yīng)用程序代碼中的所有位置都進(jìn)行更改。
          • 您可以管理多個(gè)部署環(huán)境,例如 PROD,DEV 或 TEST。在部署之間可以輕松更改環(huán)境變量,而無(wú)需更改任何應(yīng)用程序代碼。

          永遠(yuǎn)不要忘記在 .gitignore 中包含環(huán)境變量文件

          內(nèi)置操作系統(tǒng)包

          您不需要任何外部程序包即可訪問(wèn) Golang 中的環(huán)境變量,并且可以使用標(biāo)準(zhǔn)庫(kù) os 包來(lái)實(shí)現(xiàn)。以下是與環(huán)境變量有關(guān)的函數(shù)及其用途的列表。

          • os.Setenv() 設(shè)置環(huán)境值的值。
          • os.Getenv() 獲取指定鍵對(duì)應(yīng)的環(huán)境變量值。
          • os.Unsetenv() 刪除指定鍵命名對(duì)應(yīng)的單個(gè)環(huán)境值,如果我們?cè)賴L試使用 os.Getenv() 來(lái)獲取該環(huán)境值,將返回一個(gè)空值。
          • os.ExpandEnv 根據(jù)環(huán)境變量的值替換字符串中的 ${var}$var。如果不存在任何環(huán)境變量,則將使用空字符串替換它。
          • os.LookupEnv() 獲取指定鍵對(duì)應(yīng)的環(huán)境變量值。如果系統(tǒng)中不存在該變量,則返回值將為空,并且布爾值將為 false。否則,它將返回值(可以為空),并且布爾值為 true。

          如果不存在環(huán)境變量,則 os.Getenv() 將返回一個(gè)空字符串,使用 LookupEnv 來(lái)區(qū)分空值和未設(shè)置值。

          現(xiàn)在,讓我們?cè)诖a中使用上述所有函數(shù)。在一個(gè)空文件夾中創(chuàng)建一個(gè) main.go 文件。

          package?main

          import?(
          ??"fmt"
          ??"os"
          )

          func?main()?{
          ??//?Set?Environment?Variables
          ??os.Setenv("SITE_TITLE",?"Test?Site")
          ??os.Setenv("DB_HOST",?"localhost")
          ??os.Setenv("DB_PORT",?"27017")
          ??os.Setenv("DB_USERNAME",?"admin")
          ??os.Setenv("DB_PASSWORD",?"password")
          ??os.Setenv("DB_NAME",?"testdb")

          ??//?Get?the?value?of?an?Environment?Variable
          ??host?:=?os.Getenv("SITE_TITLE")
          ??port?:=?os.Getenv("DB_HOST")
          ??fmt.Printf("Site?Title:?%s,?Host:?%s\n",?host,?port)

          ??//?Unset?an?Environment?Variable
          ??os.Unsetenv("SITE_TITLE")
          ??fmt.Printf("After?unset,?Site?Title:?%s\n",?os.Getenv("SITE_TITLE"))

          ??//Checking?that?an?environment?variable?is?present?or?not.
          ??redisHost,?ok?:=?os.LookupEnv("REDIS_HOST")
          ??if?!ok?{
          ????fmt.Println("REDIS_HOST?is?not?present")
          ??}?else?{
          ????fmt.Printf("Redis?Host:?%s\n",?redisHost)
          ??}

          ??//?Expand?a?string?containing?environment?variables?in?the?form?of?$var?or?${var}
          ??dbURL?:=?os.ExpandEnv("mongodb://${DB_USERNAME}:${DB_PASSWORD}@$DB_HOST:$DB_PORT/$DB_NAME")
          ??fmt.Println("DB?URL:?",?dbURL)
          }

          下面是我們?cè)诮K端中執(zhí)行 ?go run main.go ?的輸出:

          go?run?main.go

          //?output
          Site?Title:?Test?Site,?Host:?localhost
          After?unset,?Site?Title:?27017
          REDIS_HOST?is?not?present
          DB?URL:??mongodb://admin:password@localhost:27017/testdb

          還有兩個(gè)函數(shù) os.Clearenvos.Environ(),讓我們?cè)趩为?dú)的程序中使用它們。

          • os.Clearenv ?刪除所有環(huán)境變量,清理測(cè)試環(huán)境可能很有用
          • os.Environ() 以 key = value 的形式返回包含所有環(huán)境變量的字符串的一部分。
          package?main

          import?(
          ??"fmt"
          ??"os"
          ??"strings"
          )

          func?main()?{

          ??//?Environ?returns?a?slice?of?string?containing?all?the?environment?variables?in?the?form?of?key=value.
          ??for?_,?env?:=?range?os.Environ()?{
          ????//?env?is
          ????envPair?:=?strings.SplitN(env,?"=",?2)
          ????key?:=?envPair[0]
          ????value?:=?envPair[1]

          ????fmt.Printf("%s?:?%s\n",?key,?value)
          ??}

          ??//?Delete?all?environment?variables
          ??os.Clearenv()

          ??fmt.Println("Number?of?environment?variables:?",?len(os.Environ()))
          }

          上面的函數(shù)將列出系統(tǒng)中所有可用的環(huán)境變量,包括 NAMEDB_HOST。一旦運(yùn)行os.Clearenv(),它將清除正在運(yùn)行的進(jìn)程的所有環(huán)境變量。

          GoDotEnv 包

          Ruby dotenv 項(xiàng)目啟發(fā)了 GoDotEnv[1] 包,它從 .env 文件加載環(huán)境變量。

          讓我們創(chuàng)建一個(gè) .env 文件,其中包含所有配置。

          # .env file
          # This is a sample config file

          SITE_TITLE=Test Site

          DB_HOST=localhost
          DB_PORT=27017
          DB_USERNAME=admin
          DB_PASSWORD=password
          DB_NAME=testdb

          然后在 main.go 文件中,我們將使用 godotenv 加載環(huán)境變量。

          我們也可以一次加載多個(gè) env 文件。godotenv 還支持 YAML。

          //?main.go
          package?main

          import?(
          ??"fmt"
          ??"log"
          ??"os"

          ??"github.com/joho/godotenv"
          )

          func?main()?{

          ??//?load?.env?file?from?given?path
          ??//?we?keep?it?empty?it?will?load?.env?from?current?directory
          ??err?:=?godotenv.Load(".env")

          ??if?err?!=?nil?{
          ????log.Fatalf("Error?loading?.env?file")
          ??}

          ??//?getting?env?variables?SITE_TITLE?and?DB_HOST
          ??siteTitle?:=?os.Getenv("SITE_TITLE")
          ??dbHost?:=?os.Getenv("DB_HOST")

          ??fmt.Printf("godotenv?:?%s?=?%s?\n",?"Site?Title",?siteTitle)
          ??fmt.Printf("godotenv?:?%s?=?%s?\n",?"DB?Host",?dbHost)
          }

          打開(kāi)終端并運(yùn)行 ?main.go

          go?run?main.go

          //?output
          godotenv?:?Site?Title?=?Test?Site
          godotenv?:?DB?Host?=?localhost

          Viper 包

          Viper 是 Go 應(yīng)用程序的配置的完整解決方案。它旨在在應(yīng)用程序中工作,并且可以處理所有類型的配置需求和格式。

          Viper[2] 支持多種文件格式來(lái)加載環(huán)境變量,例如,從 JSON,TOML,YAML,HCL,envfile 和 Java 屬性配置文件(properties)中讀取。因此,在此示例中,我們將研究如何從 YAML 文件中加載環(huán)境變量。

          YAML 是一種人類可讀的數(shù)據(jù)序列化語(yǔ)言。它通常用于配置文件和用于存儲(chǔ)或傳輸數(shù)據(jù)的應(yīng)用程序。

          讓我們?cè)谝粋€(gè)空文件夾中創(chuàng)建 config.yaml 和 main.go。

          #?config.yaml
          SITE:
          ??TITLE:?Test?Site

          DB:
          ??HOST:?"localhost"
          ??PORT:?"27017"
          ??USERNAME:?"admin"
          ??PASWORD:?"password"
          ??NAME:?"testdb"

          在下面的代碼中,我們使用 Viper 從 config.yaml 中加載環(huán)境變量。我們可以從所需的任何路徑加載配置文件。如果配置文件中沒(méi)有任何環(huán)境變量,我們還可以為任何環(huán)境變量設(shè)置默認(rèn)值。

          //?main.go
          package?main

          import?(
          ??"fmt"
          ??"log"
          ??"os"

          ??"github.com/spf13/viper"
          )

          func?main()?{

          ??//?Set?the?file?name?of?the?configurations?file
          ??viper.SetConfigName("config")

          ??//?Set?the?path?to?look?for?the?configurations?file
          ??viper.AddConfigPath(".")

          ??//?Enable?VIPER?to?read?Environment?Variables
          ??viper.AutomaticEnv()

          ??viper.SetConfigType("yml")

          ??if?err?:=?viper.ReadInConfig();?err?!=?nil?{
          ????fmt.Printf("Error?reading?config?file,?%s",?err)
          ??}

          ??//?Set?undefined?variables
          ??viper.SetDefault("DB.HOST",?"127.0.0.1")

          ??//?getting?env?variables?DB.PORT
          ??//?viper.Get()?returns?an?empty?interface{}
          ??//?so?we?have?to?do?the?type?assertion,?to?get?the?value
          ??DBPort,?ok?:=?viper.Get("DB.PORT").(string)

          ??//?if?type?assert?is?not?valid?it?will?throw?an?error
          ??if?!ok?{
          ????log.Fatalf("Invalid?type?assertion")
          ??}

          ??fmt.Printf("viper?:?%s?=?%s?\n",?"Database?Port",?DBPort)
          }

          打開(kāi)終端并運(yùn)行 main.go

          go?run?main.go

          //?output
          viper?:?Database?Port?=?27017

          結(jié)論

          使用環(huán)境變量是在我們的應(yīng)用程序中處理配置的絕佳方法。總體而言,它為您提供了輕松的配置,更好的安全性,多個(gè)部署環(huán)境以及更少的生產(chǎn)錯(cuò)誤。

          現(xiàn)在您可以在 go 應(yīng)用程序中管理環(huán)境變量,并且可以在我們的 Github Repo[3] 上找到本教程中使用的完整代碼。

          原文鏈接:https://www.loginradius.com/engineering/blog/environment-variables-in-golang/

          作者:Puneet Singh

          編譯:polarisxu

          參考資料

          [1]

          GoDotEnv: https://github.com/joho/godotenv

          [2]

          Viper: https://github.com/spf13/viper

          [3]

          Github Repo: https://github.com/LoginRadius/engineering-blog-samples/tree/master/GoLang/EnvironmentVariables



          推薦閱讀


          福利

          我為大家整理了一份從入門到進(jìn)階的Go學(xué)習(xí)資料禮包,包含學(xué)習(xí)建議:入門看什么,進(jìn)階看什么。關(guān)注公眾號(hào) 「polarisxu」,回復(fù) ebook 獲??;還可以回復(fù)「進(jìn)群」,和數(shù)萬(wàn) Gopher 交流學(xué)習(xí)。

          瀏覽 49
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  欧美日逼视频网址 | av小说天堂 | 国产女人18毛片水18精品软件 | 99操免费视频 | 黑几巴视频久久 |