【问题标题】:Authenticate users on certain handle requests对某些句柄请求的用户进行身份验证
【发布时间】:2019-04-05 02:03:32
【问题描述】:

是否有更有效的方法来验证某些句柄请求的用户?现在我正在调用一个函数来根据请求令牌进行身份验证,但我正在为每个句柄函数执行此操作。

func GetCompanies(w http.ResponseWriter, r *http.Request) {
    //Authentication
    token := r.Header.Get("Authorization")
    err := auth.AuthenticateUser(token)
    if err != nil {
        if custom, ok := err.(*errors.MyErrorType); ok {
            fmt.Println(custom.Error())
            w.WriteHeader(custom.Code)
            _ = json.NewEncoder(w).Encode("Error: " + custom.Msg)
        } else {
            fmt.Println(err)
            w.WriteHeader(500)
        }
        return
    }
    //If user is authenticated do other stuff
}

我尝试过使用中间件,但它适用于每个句柄函数。我希望未经身份验证的用户访问某些 API

func loggingMiddleware(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        // Do stuff here
        fmt.Println(r.URL)
        // Call the next handler, which can be another middleware in the chain, or the final handler.
        next.ServeHTTP(w, r)
    })
}

func HandleFunctions() {
    //Init Router
    r := mux.NewRouter()
    r.Use(loggingMiddleware)

    //API Paths that do not require Auth
        r.HandleFunc("/login", handlers.Authenticate).Methods("POST")
        //API Paths that require auth
        r.HandleFunc("/stuff", handlers.PostThings).Methods("POST")
}

我还希望将来能够实现用户角色,以便根据安全权限不同的路径可用或不可用。

最有效的方法是什么?

【问题讨论】:

    标签: rest go mux


    【解决方案1】:

    您实际上并不需要中间件。您可以通过将处理程序包装到通用身份验证函数来实现此目的。 看看下面的代码,我想它会做你想要的。

        func grant(fn func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
            return func(w http.ResponseWriter, r *http.Request) {
    
                //Place your logic to authenticate users here
                //This is only a snippet. You have to adapt the code to your needs.
    
                token := r.Header.Get("Authorization")
                if err := auth.AuthenticateUser(token); err != nil {
                    //If error is returned. The grant function will return error
                    // and abort execution and therefore not reaching your handler
                    http.Error(w, "Authentication is Invalid", http.StatusInternalServerError)
                    return
                }
                //If Authentication is valid your handler function will be executed
                fn(w, r)
            }
        }
    
    
        // Define your handler functions as you'd normally do
        func handler(w http.ResponseWriter, r *http.Request) {
          fmt.Fprint(w,"Success")
        }
    
    
        func main() {
          //Then wrap the handlers that need authentication around the grant function
          http.HandleFunc("/your/url/path", grant(handler))
    
          //For endpoints that don't need authentication, simply pass the handler as usual without the grant function
          http.HandleFunc("/your/url/path/noauth", anotherHandler)
        }
    

    函数“grant”以 http.HandlerFunc 类型的函数作为参数。在这种情况下是处理程序本身。

    func handler(w http.ResponseWriter, r *http.Request)

    因此,该函数必须有一个 http.ResponseWriter 和 *http.Request 作为参数。这与 http.HandleFunc 的要求相同。

    http.HandleFunc("/your/url/path", 处理程序)

    grant 函数所做的基本上是将您的处理程序作为参数,如果一切顺利,grant 会以与 http.HandleFunc 相同的方式执行您的处理程序。

    fn(w, r)

    如果身份验证失败,授权将返回错误并且永远不会到达您的处理程序的执行。

    【讨论】:

    • 那行得通。你介意解释一下这个函数的各个部分,以便我了解发生了什么吗? unc grant(fn func(http.ResponseWriter, *http.Request)) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request)
    猜你喜欢
    • 1970-01-01
    • 2013-11-22
    • 2023-04-08
    • 1970-01-01
    • 2014-12-20
    • 1970-01-01
    • 2021-11-18
    • 2017-10-14
    • 1970-01-01
    相关资源
    最近更新 更多