在GoLang中如何让HandleFunc()函数将json解析为函数外部可访问的变量

时间:2017-01-25 14:42:45

标签: json go active-directory ldap httphandler

我正在尝试使用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
}

2 个答案:

答案 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())
    }