我正在尝试使用golang创建一个服务,该服务将在端口上侦听包含json的post请求,并希望解析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
}
// 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
}
答案 0 :(得分:1)
您不能访问变量,因为Go命名空间不允许,但因为ListenAndServe
阻塞而且ldapConn
只有在服务器停止时才能被调用。
log.Fatal(http.ListenAndServe(":" + SERVICE_PORT, nil))
// Blocked until the server is listening and serving.
connected := ldapConn(LDAP_SERVER_DOMAIN, uname, pwd)
更正确的方法是在ldapConn
回调中调用http.HandleFunc
。
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))
答案 1 :(得分:0)
从你的问题如何让HandleFunc()函数将json解析为变量 在功能之外可以访问?
我认为你不能在这里返回json值。相反,您可以将结构传递给函数并在其中调用它们。 例如:
//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)
})
您可以在另一个包中编写yourFunction(m Message)
或在定义处理程序时使用相同的包。例如,写yourFunction()
将是:
func yourFunction(m Message){
// do your logic here
}
如果函数在另一个包中
//call your package where your struct is defined.
func yourFunction(m main.Message){
// do your logic here
}
JimB说。在ldapConn
之后,您正在调用ListenAndServe
这些行,因为它被阻止,所以永远不会被执行。
如果您想打印您的应用程序已启动或失败。我认为此代码可以帮助您:
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())
}