duanci1939 2019-04-05 02:03
浏览 46
已采纳

根据某些句柄请求对用户进行身份验证

Is there a more efficient way to authenticate users on certain handle requests? Right now I am calling a function to authenticate based off of the request token but am doing that for every handle function.

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
}

I have tried using middleware but it runs for every handle function. I want unauthenticated users to access certain API's

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

I also want to be able to implement user roles in the future so based on security permissions different paths will be available or not.

What is the most efficient way to do this?

  • 写回答

1条回答 默认 最新

  • dounai9592 2019-04-05 02:23
    关注

    You don't really need a middleware for that. You can achieve this by wrapping your handlers to a generic authentication function. Take a look at the code below, I think it will do what you're looking for.

        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)
        }
    

    Function "grant" takes a function of type http.HandlerFunc as argument. Which in this case is the handler itself.

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

    The function therefore must have an http.ResponseWriter and *http.Request as arguments. Which is the same required by http.HandleFunc.

    http.HandleFunc("/your/url/path", handler)

    What the grant function is doing is basically taking your handler as an argument and if all goes well, grant executes your handler the same way http.HandleFunc would do.

    fn(w, r)

    If authentication fails, grant will return error and will never reach the execution of your handler.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 装 pytorch 的时候出了好多问题,遇到这种情况怎么处理?
  • ¥20 IOS游览器某宝手机网页版自动立即购买JavaScript脚本
  • ¥15 手机接入宽带网线,如何释放宽带全部速度
  • ¥30 关于#r语言#的问题:如何对R语言中mfgarch包中构建的garch-midas模型进行样本内长期波动率预测和样本外长期波动率预测
  • ¥15 ETLCloud 处理json多层级问题
  • ¥15 matlab中使用gurobi时报错
  • ¥15 这个主板怎么能扩出一两个sata口
  • ¥15 不是,这到底错哪儿了😭
  • ¥15 2020长安杯与连接网探
  • ¥15 关于#matlab#的问题:在模糊控制器中选出线路信息,在simulink中根据线路信息生成速度时间目标曲线(初速度为20m/s,15秒后减为0的速度时间图像)我想问线路信息是什么