7

I am trying to pass an additional parameter in the request I am trying to send to the Go server -

websocket.create_connection("ws://<ip>:port/x/y?token="qwerty")

The Go server implementation is as follows -

func main() {
    err := config.Parse()
    if err != nil {
        glog.Error(err)
        os.Exit(1)
        return
    }

    flag.Parse()
    defer glog.Flush()

    router := mux.NewRouter()
    http.Handle("/", httpInterceptor(router))

    router.Handle("/v1/x", common.ErrorHandler(stats.GetS)).Methods("GET")
    router.Handle("/v1/x/y", common.ErrorHandler(stats.GetS)).Methods("GET")

    var listen = fmt.Sprintf("%s:%d", config.Config.Ip, config.Config.Port)
    err = http.ListenAndServe(listen, nil)

    if err != nil {
        glog.Error(err)
        os.Exit(1)
    }
}

func httpInterceptor(router http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
        startTime := time.Now()

        if !auth.Auth(w, req) {
            http.Error(w, "Failed authentication", 401)
            return
        }

        router.ServeHTTP(w, req)

        finishTime := time.Now()
        elapsedTime := finishTime.Sub(startTime)

        switch req.Method {
        case "GET":
        case "POST":
        }

    })
}

How should I look and parse for the token in the Go server so that the authentication is successful?

Library function

func ParseFromRequest(req *http.Request, keyFunc Keyfunc) (token *Token, err error) {

    // Look for an Authorization header
    if ah := req.Header.Get("Authorization"); ah != "" {
        // Should be a bearer token
        if len(ah) > 6 && strings.ToUpper(ah[0:6]) == "BEARER" {
            return Parse(ah[7:], keyFunc)
        }
    }

    // Look for "access_token" parameter
    req.ParseMultipartForm(10e6)
    if tokStr := req.Form.Get("access_token"); tokStr != "" {
        return Parse(tokStr, keyFunc)
    }

    return nil, ErrNoTokenInRequest

}
Charlie Tumahai
  • 113,709
  • 12
  • 249
  • 242
psbits
  • 1,787
  • 5
  • 19
  • 34

3 Answers3

16

Call FormValue to get a query parameter:

token := req.FormValue("token")

req is a the *http.Request

An alternative is to call ParseForm and access req.Form directly:

if err := req.ParseForm(); err != nil {
   // handle error
}
token := req.Form.Get("token")

The OP asks in a comment how to map "token" to "access_token" for an external package that's looking "access_token". Execute this code before calling the external package:

if err := req.ParseForm(); err != nil {
   // handle error
}
req.Form["access_token"] = req.Form["token"]

When the external package calls req.Form.Get("access_token"), it will get the same value as the "token" parameter.

Nik
  • 2,885
  • 2
  • 25
  • 25
Charlie Tumahai
  • 113,709
  • 12
  • 249
  • 242
  • How about i use something like this - token := req.URL.Query().Get("token") – psbits Jan 26 '15 at 22:06
  • Cool, thanks , How do i pass in this token parameter to the Auth function being used in the code above ? Another question is have that the external library i am using looks for "access_token" parameter and in my server code, i would add this logic to handle "token" parameter. How can i internally map "token" to "Access_token" so that the library can successfully authenticate this token being passed in the request? – psbits Jan 26 '15 at 22:16
  • This is the Auth function token, err := jwt.ParseFromRequest(req, func(token *jwt.Token) (interface{}, error) { return config.Config.Key, nil }) – psbits Jan 26 '15 at 22:50
  • The library has the implementation of ParseFromRequest which looks like this - func ParseFromRequest(req *http.Request, keyFunc Keyfunc) (token *Token, err error) { // Look for an Authorization header if ah := req.Header.Get("Authorization"); ah != "" { // Should be a bearer token if len(ah) > 6 && strings.ToUpper(ah[0:6]) == "BEARER" { return Parse(ah[7:], keyFunc) } } // Look for "access_token" parameter req.ParseMultipartForm(10e6) if tokStr := req.Form.Get("access_token"); tokStr != "" { return Parse(tokStr, keyFunc) } return nil, ErrNoTokenInRequest } – psbits Jan 26 '15 at 22:50
  • Pasted the above function in the description on the top. – psbits Jan 26 '15 at 22:51
  • I see, thanks 3of3 , I will let you know if this worked for me. I am interested in authenticating this request as you would have seen by passing the token. – psbits Jan 26 '15 at 23:10
  • Is there a way that I use req.URL.Query().Get("token") to fetch the token and be able to assign it to req.Form("access_token") ? – psbits Jan 27 '15 at 21:40
5

Depending on the way you want to parse the token , if its coming from the form or the URL.

The first answer can be used if the token is being sent from the form while in case of a URL, I would suggest using this. This works for me

token := req.URL.Query().Get("token")
psbits
  • 1,787
  • 5
  • 19
  • 34
0

For url query parameters:

mux.Vars(r)["token"]
bluehallu
  • 10,205
  • 9
  • 44
  • 61