【问题标题】:Passing a query parameter to the Go HTTP request handler using the MUX package使用 MUX 包将查询参数传递给 Go HTTP 请求处理程序
【发布时间】:2015-03-25 10:06:00
【问题描述】:

我正在尝试在我尝试发送到 Go 服务器的请求中传递一个附加参数 -

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

Go服务器实现如下-

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":
        }

    })
}

我应该如何在 Go 服务器中查找和解析令牌以使身份验证成功?

图书馆功能

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

}

【问题讨论】:

    标签: http authentication go mux


    【解决方案1】:

    调用FormValue获取查询参数:

    token := req.FormValue("token")
    

    req*http.Request

    另一种方法是调用ParseForm 并直接访问req.Form

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

    OP 在评论中询问如何将 "token" 映射到 "access_token" 以获取正在查找 "access_token" 的外部包。在调用外部包之前执行这段代码:

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

    当外部包调用req.Form.Get("access_token")时,会得到与"token"参数相同的值。

    【讨论】:

    • 我用这样的东西怎么样 - token := req.URL.Query().Get("token")
    • 酷,谢谢,我如何将此令牌参数传递给上面代码中使用的 Auth 函数?另一个问题是我正在使用的外部库查找“access_token”参数,并且在我的服务器代码中,我会添加这个逻辑来处理“token”参数。我如何在内部将“令牌”映射到“Access_token”,以便库可以成功验证请求中传递的这个令牌?
    • 库如何获取查询参数?它使用 req.Form 吗?
    • 这是 Auth 函数令牌,err := jwt.ParseFromRequest(req, func(token *jwt.Token) (interface{}, error) { return config.Config.Key, nil })
    • 该库有 ParseFromRequest 的实现,看起来像这样 - func ParseFromRequest(req *http.Request, keyFunc Keyfunc) (token *Token, err error) { // 寻找授权头 if ah := req.Header.Get("授权"); ah != "" { // 应该是不记名令牌 if len(ah) > 6 && strings.ToUpper(ah[0:6]) == "BEARER" { return Parse(ah[7:], keyFunc) } } // 查找“access_token”参数 req.ParseMultipartForm(10e6) if tokStr := req.Form.Get("access_token"); tokStr != "" { return Parse(tokStr, keyFunc) } return nil, ErrNoTokenInRequest }
    【解决方案2】:

    取决于您想要解析令牌的方式,如果它来自表单或 URL。

    如果令牌是从表单发送的,则可以使用第一个答案,而如果是 URL,我建议使用它。这对我有用

    token := req.URL.Query().Get("token")
    

    【讨论】:

    • Query 方法在每次调用该方法时都会解析查询字符串。首选方法是通过调用ParseForm 并访问请求Form 字段中的已解析参数来解析一次查询字符串。 FormValue 是一个有用的辅助方法,它结合了这两个步骤。
    【解决方案3】:

    对于url查询参数:

    mux.Vars(r)["token"]
    

    【讨论】:

      猜你喜欢
      • 2012-08-28
      • 2015-04-02
      • 2020-12-17
      • 2016-02-12
      • 1970-01-01
      • 2015-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多