In GoLang How do I get the HandleFunc() function to parse a json into variables accesible outside of the function

huangapple go评论73阅读模式
英文:

In GoLang How do I get the HandleFunc() function to parse a json into variables accesible outside of the function

问题

我正在尝试使用Go语言创建一个服务,该服务将在一个端口上监听POST请求,该请求包含JSON数据,并且我想解析JSON数据中的用户名和密码字段,并将它们保存为变量,以便在函数外部使用以进行Active Directory身份验证。
我正在使用HandleFunc()函数,但无法弄清楚如何在函数外部访问这些变量。我尝试创建一个返回值,但无法构建。如何正确创建这些变量并在函数外部使用它们?

package main

import (
	"gopkg.in/ldap.v2"
	"fmt"
	"net/http"
	"os"
	"encoding/json"
	"log"
	"crypto/tls"
	"html"
)

type Message struct {
	User     string
	Password string
}

func main() {
	const SERVICE_PORT = "8080"

	var uname string
	var pwd string

	LDAP_SERVER_DOMAIN := os.Getenv("LDAP_DOM")
	if LDAP_SERVER_DOMAIN == "" {
		LDAP_SERVER_DOMAIN = "192.168.10.0"
	}

	//Handle Http request and parse json
	http.HandleFunc("/", func(w http.ResponseWriter, request *http.Request) {
		var m Message

		if request.Body == nil {
			http.Error(w, "Please send a request body", 400)
			return
		}

		err := json.NewDecoder(request.Body).Decode(&m)
		if err != nil {
			http.Error(w, err.Error(), 400)
			return
		}

		uname = m.User
		pwd = m.Password
	})

	log.Fatal(http.ListenAndServe(":"+SERVICE_PORT, nil))

	connected := ldapConn(LDAP_SERVER_DOMAIN, uname, pwd)

	if connected == true {
		fmt.Println("Connected is", connected)
	}
}

// Connects to the ldap server and returns true if successful
func ldapConn(dom, user, pass string) bool {
	// For testing go insecure
	tlsConfig := &tls.Config{InsecureSkipVerify: true}

	conn, err := ldap.DialTLS("tcp", dom, tlsConfig)
	if err != nil {
		// error in connection
		log.Println("ldap.DialTLS ERROR:", err)

		//debug
		fmt.Println("Error", err)

		return false
	}
	defer conn.Close()
	err = conn.Bind(user, pass)
	if err != nil {
		// error in ldap bind
		log.Println(err)

		//debug
		log.Println("conn.Bind ERROR:", err)

		return false
	}
	return true
}

以上是你提供的代码的翻译。

英文:

I am trying to create a service using golang that will listen on a port for a post request containing json and would like to parse out the username and password fields of the json and save those as variables to be used outside of the function to authenticate to Active Directory.
I am using the HandleFunc() fucntion, but cannot ficure out how to access the variables outside of the function. I tried creating a return, but it wouldn't build. How do I properly create the variables and then use them outside of the function?

 package main
import (
"gopkg.in/ldap.v2"
"fmt"
"net/http"
"os"
"encoding/json"
"log"
"crypto/tls"
"html"
)
type Message struct {
User string 
Password string 
}
func main() {
const SERVICE_PORT = "8080"
var uname string
var pwd string
LDAP_SERVER_DOMAIN := os.Getenv("LDAP_DOM")
if LDAP_SERVER_DOMAIN == "" {
LDAP_SERVER_DOMAIN = "192.168.10.0"	
}
//Handle Http request and parse json
http.HandleFunc("/", func(w http.ResponseWriter, request *http.Request) {
var m Message
if request.Body == nil {
http.Error(w, "Please send a request body", 400)	            
return
}
err := json.NewDecoder(request.Body).Decode(&m)
if err != nil {
http.Error(w, err.Error(), 400)
return
}
// Not sure what to do here
uname = m.User
pwd = m.Password
})
log.Fatal(http.ListenAndServe(":" + SERVICE_PORT, nil))
connected := ldapConn(LDAP_SERVER_DOMAIN, uname, pwd)
if connected == true {
fmt.Println("Connected is", connected)
}
}
// Connects to the ldap server and returns true if successful
func ldapConn(dom, user, pass string) bool {
// For testing go insecure
tlsConfig := &tls.Config{InsecureSkipVerify: true}
conn, err := ldap.DialTLS("tcp", dom, tlsConfig)
if err != nil {
// error in connection
log.Println("ldap.DialTLS ERROR:", err)
//debug
fmt.Println("Error", err)
return false
}
defer conn.Close()
err = conn.Bind(user, pass)
if err != nil {
// error in ldap bind
log.Println(err)
//debug
log.Println("conn.Bind ERROR:", err)
return false
}
return true
}

答案1

得分: 1

你无法访问变量的原因不是因为Go的命名空间不允许,而是因为ListenAndServe是阻塞的,只有在服务器停止时才能调用ldapConn

更正确的方法是在http.HandleFunc的回调函数中调用ldapConn

http.HandleFunc("/", func(w http.ResponseWriter, request *http.Request) {
    var m Message

    if request.Body == nil {
        http.Error(w, "Please send a request body", 400)
        return
    }

    err := json.NewDecoder(request.Body).Decode(&m)
    if err != nil {
        http.Error(w, err.Error(), 400)
        return
    }

    connected := ldapConn(LDAP_SERVER_DOMAIN, m.User, m.Password)
    if connected == true {
        fmt.Println("Connected is", connected)
    }
})

log.Fatal(http.ListenAndServe(":"+SERVICE_PORT, nil))
英文:

You can't access the variables not because Go namespaces not allow it but because ListenAndServe is blocking and ldapConn could be called only if the server is stopped.

 log.Fatal(http.ListenAndServe(":" + SERVICE_PORT, nil))
// Blocked until the server is listening and serving.
connected := ldapConn(LDAP_SERVER_DOMAIN, uname, pwd)

A more correct approach is to call ldapConn inside http.HandleFunc callback.

 http.HandleFunc("/", func(w http.ResponseWriter, request *http.Request) {
var m Message
if request.Body == nil {
http.Error(w, "Please send a request body", 400)                
return
}
err := json.NewDecoder(request.Body).Decode(&m)
if err != nil {
http.Error(w, err.Error(), 400)
return
}
connected := ldapConn(LDAP_SERVER_DOMAIN, m.User, m.Password)
if connected == true {
fmt.Println("Connected is", connected)
}
})
log.Fatal(http.ListenAndServe(":" + SERVICE_PORT, nil))

答案2

得分: 0

如何使HandleFunc()函数解析JSON并将其转换为函数外部可访问的变量?

根据你的问题,我认为你不能在这里返回JSON值。相反,你可以将结构体传递给一个函数,并在函数内部调用它们。
例如:

// 处理HTTP请求并解析JSON
http.HandleFunc("/", func(w http.ResponseWriter, request *http.Request) {
    var m Message

    if request.Body == nil {
        http.Error(w, "Please send a request body", 400)
        return
    }

    err := json.NewDecoder(request.Body).Decode(&m)
    if err != nil {
        http.Error(w, err.Error(), 400)
        return
    }

    // 不确定在这里该怎么做
    // 将变量传递给你的函数
    uname := m.User
    pwd := m.Password

    // 在这里将你的结构体传递给一个函数,并在那里进行逻辑处理。
    yourFunction(m)
})

你可以在另一个包或与定义处理程序相同的包中编写yourFunction(m Message)。例如,编写yourFunction()的代码如下:

func yourFunction(m Message) {
    // 在这里进行逻辑处理
}

如果函数在另一个包中:

// 调用定义了你的结构体的包。
func yourFunction(m main.Message) {
    // 在这里进行逻辑处理
}

正如JimB所说,你在ListenAndServe之后调用了ldapConn,这些行将不会被执行,因为它被阻塞了。

如果你想打印应用程序启动或失败的消息,我认为以下代码会对你有所帮助:

log.Println("App started on port =", port)
err := http.ListenAndServe(":"+port, nil)
if err != nil {
    log.Panic("App Failed to start on =", port, " Error :", err.Error())
}
英文:

> How do I get the HandleFunc() function to parse a json into variables
> accesible outside of the function?

from your question I don't think you can return the json value here. Instead you could pass the struct to a function and call them inside it.
for example :

//Handle Http request and parse json
http.HandleFunc("/", func(w http.ResponseWriter, request *http.Request) {
var m Message
if request.Body == nil {
http.Error(w, "Please send a request body", 400)                
return
}
err := json.NewDecoder(request.Body).Decode(&m)
if err != nil {
http.Error(w, err.Error(), 400)
return
}
// Not sure what to do here
// pass the variable to your function
uname = m.User
pwd = m.Password
// passed your struct to a function here and do your logic there.
yourFunction(m)
})

and you can write yourFunction(m Message) in another package or the same package as you define your handler. for example writing yourFunction() would be :

func yourFunction(m Message){
// do your logic here
}

if function is in another package

//call your package where your struct is defined.
func yourFunction(m main.Message){
// do your logic here
}

as JimB said. You're calling your ldapConn after ListenAndServe those lines would never be executed since it is blocked.

and if you like to print your app is started or failed. I think this code will help you :

    log.Println("App started on port = ", port)
err := http.ListenAndServe(":"+port, nil)
if err != nil {
log.Panic("App Failed to start on = ", port, " Error : ", err.Error())
}

huangapple
  • 本文由 发表于 2017年1月25日 22:42:45
  • 转载请务必保留本文链接:https://go.coder-hub.com/41854398.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定