Golang代码运行时如何提示用户输入密码

Golang代码运行时如何提示用户输入密码 大家好, 希望各位本周一切顺利。我正在尝试让我的代码提示用户输入密码。目前,如果运行代码并使用 --help 参数,会看到几个标志参数。因此,我不希望用户通过终端提示显示他们的密码。基本上,就是提供参数并运行代码,然后输入密码。希望我解释清楚了我的意图。我在 Go 语言方面还是个新手。

示例:


-ipAddress string 要添加的被管理服务器的 IP 地址 -password string HMC 用户密码 -url string HMC REST API URL -user string HMC 用户


package main

import (
	"bytes"
	"crypto/tls"
	"encoding/xml"
	"flag"
	"fmt"
	"io/ioutil"
	"log"
	"net/http"
	"net/http/cookiejar"
	"text/template"
    "golang.org/x/crypto/ssh/terminal"
)
//
// XML parsing structures
//
type Feed struct {
	Entry struct {
		Content struct {
			ManagementConsole struct {
				Metadata struct {
					Atom struct {
						AtomID      string `xml:"AtomID"`
						AtomCreated string `xml:"AtomCreated"`
					} `xml:"Atom"`
				} `xml:"Metadata"`
			} `xml:"ManagementConsole"`
		} `xml:"content"`
	} `xml:"entry"`
}

// HTTP session struct
//
type Session struct {
	client   *http.Client
	User     string
	Password string
	url      string
}
type Manage struct {
	Ipaddress string
}
func NewSession(user string, password string, url string) *Session {
	tr := &http.Transport{
		TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
	}
	jar, err := cookiejar.New(nil)
	if err != nil {
		log.Fatal(err)
	}
	return &Session{client: &http.Client{Transport: tr, Jar: jar}, User: user, Password: password, url: url}
}
func (s *Session) doLogon() {
	authurl := s.url + "/rest/api/web/Logon"
	// template for login request
	logintemplate := `<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
  <LogonRequest xmlns="http://www.ibm.com/xmlns/systems/power/firmware/web/mc/2012_10/" schemaVersion="V1_1_0">
    <Metadata>
      <Atom/>
    </Metadata>
    <UserID kb="CUR" kxe="false">{{.User}}</UserID>
    <Password kb="CUR" kxe="false">{{.Password}}</Password>
  </LogonRequest>`
	tmpl := template.New("logintemplate")
	tmpl.Parse(logintemplate)
	authrequest := new(bytes.Buffer)
	err := tmpl.Execute(authrequest, s)
	if err != nil {
		log.Fatal(err)
	}
	request, err := http.NewRequest("PUT", authurl, authrequest)
	// set request headers

	request.Header.Set("Content-Type", "application/vnd.ibm.powervm.web+xml; type=LogonRequest")
	request.Header.Set("Accept", "application/vnd.ibm.powervm.web+xml; type=LogonResponse")
	request.Header.Set("X-Audit-Memento", "hmctest")
	response, err := s.client.Do(request)
	fmt.Println("\n")
	fmt.Println(response)
	if err != nil {
		log.Fatal(err)
	} else {
		defer response.Body.Close()
		if response.StatusCode != 200 {
			log.Fatalf("Error status code: %d", response.StatusCode)
		}
	}
}
func (s *Session) getManaged()(string) {
	hmcUUID :=""
	// mgdurl := s.url + "/rest/api/uom/LogicalPartition"
	mgdurl := s.url + "/rest/api/uom/ManagementConsole"
	request, err := http.NewRequest("GET", mgdurl, nil)
	request.Header.Set("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8")
	response, err := s.client.Do(request)
	if err != nil {
		log.Fatal(err)
	} else {
		defer response.Body.Close()
		contents, err := ioutil.ReadAll(response.Body)
		if err != nil {
			log.Fatal(err)
		}
		if response.StatusCode != 200 {
			log.Fatalf("Error getting LPAR informations. status code: %d", response.StatusCode)
		}
		var feed Feed
		new_err := xml.Unmarshal(contents, &feed)
		if new_err != nil {
			log.Fatal(new_err)
		}
		fmt.Printf("AtomID: %v\n", feed.Entry.Content.ManagementConsole.Metadata.Atom.AtomID)
		fmt.Printf("AtomCreated: %v\n", feed.Entry.Content.ManagementConsole.Metadata.Atom.AtomCreated)
		hmcUUID = feed.Entry.Content.ManagementConsole.Metadata.Atom.AtomID

	}

	return hmcUUID
}
func (s *Session) addManaged(uuid *string, i *Manage){
	addManagedURl := s.url + "/rest/api/uom/ManagementConsole/" + *uuid + "/do/AddManagedSystem"
	addManagedTemplate := `<JobRequest:JobRequest
 xmlns:JobRequest="http://www.ibm.com/xmlns/systems/power/firmware/web/mc/2012_10/"
 xmlns="http://www.ibm.com/xmlns/systems/power/firmware/web/mc/2012_10/"
 xmlns:ns2="http://www.w3.org/XML/1998/namespace/k2" schemaVersion="V1_0">
       <Metadata>
           <Atom/>
       </Metadata>
       <RequestedOperation kb="CUR" kxe="false" schemaVersion="V1_0">
           <Metadata>
               <Atom/>
           </Metadata>
           <OperationName kb="ROR" kxe="false">AddManagedSystem</OperationName>
           <GroupName kb="ROR" kxe="false">ManagementConsole</GroupName>
       </RequestedOperation>
       <JobParameters kb="CUR" kxe="false" schemaVersion="V1_0">
           <Metadata>
               <Atom/>
           </Metadata>
         <JobParameter schemaVersion="V1_0"><Metadata><Atom/></Metadata>
            <ParameterName kb="ROR" kxe="false">host</ParameterName>
            <ParameterValue kb="CUR" kxe="false">{{.Ipaddress}}</ParameterValue>
         </JobParameter>
        <JobParameter schemaVersion="V1_0"><Metadata><Atom/></Metadata>
            <ParameterName kb="ROR" kxe="false">password</ParameterName>
            <ParameterValue kb="CUR" kxe="false">abcc123</ParameterValue>
         </JobParameter>
       </JobParameters>
   </JobRequest:JobRequest>  `
	tmpl := template.New("addManagedTemplate")
	tmpl.Parse(addManagedTemplate)
	addrequest := new(bytes.Buffer)
	err := tmpl.Execute(addrequest, i)
	if err != nil {
		log.Fatal(err)
	}
	request, err := http.NewRequest("PUT", addManagedURl, addrequest)
	// set request headers
	request.Header.Set("Content-Type", "application/vnd.ibm.powervm.web+xml; type=JobRequest")
	request.Header.Set("Accept", "application/atom+xml; charset=UTF-8")
	// request.Header.Set("Expect", "")
	response, err := s.client.Do(request)
	fmt.Println("\n")
	fmt.Println(response)
	if err != nil {
		log.Fatal(err)
	} else {
		defer response.Body.Close()
		if response.StatusCode != 200 {
			log.Fatalf("Error status code: %d", response.StatusCode)
		}
	}
}
func readPassword(prompt string) string {
	fmt.Print(prompt)
	pass, err := terminal.ReadPassword(int(os.Stdin.Fd()))
	if err != nil {
		panic(err)
	}
	println()
	return string(pass)
}

func main() {
	// Variables
	password := readPassword("hmc Password: ")
	//confirm := readPassword("Confirm hmc Password: ")
	user := flag.String("user", "", "hmc user")
	password := flag.String("password", "", "hmc user password")
	url := flag.String("url", "", "hmc REST api url")
	ipAddress := flag.String("ipAddress", "", "ip address of the managed server to be added")
	flag.Parse()
	//initialize new http session
	fmt.Printf("server %s is being added.../n", *ipAddress)
	session := NewSession(*user, *password, *url)
	//var password string = readPassword("hmc password")
	session.doLogon()
	hmcUUID := session.getManaged()
	ipaddr := &Manage {
		Ipaddress: *ipAddress,
	}
	session.addManaged(&hmcUUID, ipaddr)
	fmt.Println(hmcUUID)
}

更多关于Golang代码运行时如何提示用户输入密码的实战教程也可以访问 https://www.itying.com/category-94-b0.html

1 回复

更多关于Golang代码运行时如何提示用户输入密码的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


在Go语言中,可以通过标准库的syscall包或golang.org/x/crypto/ssh/terminal包(已迁移到golang.org/x/term)来安全地提示用户输入密码,避免在终端显示明文。以下是修改后的代码示例:

package main

import (
    "flag"
    "fmt"
    "os"
    "syscall"
    "golang.org/x/term"
)

func readPassword(prompt string) string {
    fmt.Print(prompt)
    bytePassword, err := term.ReadPassword(int(syscall.Stdin))
    if err != nil {
        panic(err)
    }
    fmt.Println()
    return string(bytePassword)
}

func main() {
    user := flag.String("user", "", "HMC user")
    url := flag.String("url", "", "HMC REST API URL")
    ipAddress := flag.String("ipAddress", "", "IP address of the managed server to be added")
    flag.Parse()

    // 交互式提示输入密码
    password := readPassword("HMC Password: ")

    fmt.Printf("User: %s\n", *user)
    fmt.Printf("URL: %s\n", *url)
    fmt.Printf("IP Address: %s\n", *ipAddress)
    fmt.Printf("Password length: %d\n", len(password))

    // 后续使用这些参数进行会话管理...
}

如果希望只在未通过命令行参数提供密码时才提示输入,可以这样修改:

func main() {
    var password string
    flagPassword := flag.String("password", "", "HMC user password")
    user := flag.String("user", "", "HMC user")
    url := flag.String("url", "", "HMC REST API URL")
    ipAddress := flag.String("ipAddress", "", "IP address of the managed server to be added")
    flag.Parse()

    if *flagPassword == "" {
        password = readPassword("HMC Password: ")
    } else {
        password = *flagPassword
    }

    // 使用参数继续执行...
}

注意:原代码中导入了golang.org/x/crypto/ssh/terminal,但该包已废弃,建议使用golang.org/x/term替代。

回到顶部