Web 应用程序中的 Go- 身份验证逻辑模式

我想在用 golang 编写的 Web 应用程序中确定一种简单而有用的用户身份验证模式。


我想出了两种模式。第一个是使程序员能够将他的功能与身份验证逻辑分开,并且具有更清晰的HandleFunc部分,main()因为人们只能通过main()查看哪些部分在身份验证控制下才能看到。


第二个是让程序员在每个函数中包含一个处理身份验证所需 url 的决定。一个if由语句检查authp()功能,其他地方定义。


对于这种必要性,哪一种是更好的模式?


这项工作的更好模式是什么?


如果不是一个合适的解决方法,是否甚至可以将一个函数传递给 http.HandleFunc,该函数具有除func urlFunc (ResponseWriter, *Request)bu likefunc urlFunc (successFunc, failFunc)或func urlFunc (ResponseWriter, *Request, successFunc, failFunc)as in authenticationGateKeeperfunction of First Way以外的签名?


//First Way

package main


func authGateKeeper(successFunc, failFunc) {

    if (authp()) {

        successFunc

    } else {

        failFunc

    }

}


func authp() boolean {

    //authentication logic, db query, or session check etc.

}


//usage in main

http.HandleFunc("/", authGateKeeper)




//Second Way; other alternative, in each function check pattern

func f(w, r) {

    if (authp()) {

    //function's processes

    } else {

    //the fail case function or processes

    }

}


func authp() boolean {

    //authentication logic, db query, or session check etc.

}


//usage in main

http.HandleFunc("/", f)


扬帆大鱼
浏览 157回答 1
1回答

BIG阳

有很多方法可以解决这个问题,其中一种是否完全“更好”是有争议的。我强烈建议编写一些中间件来包装您的路由并强制执行检查,仅在成功时调用包装的处理程序。请注意,我将在这里做一些假设,因为您没有告诉我们您如何管理会话(cookies?服务器端?)和/或除了身份验证之外您可能需要什么样的授权。// Middleware - a function that sits in the 'middle' of your request processing.func RequireAuth(h http.Handler) http.Handler) {    fn := func(w http.ResponseWriter, r *http.Request) {        // Assuming gorilla/sessions        session, err := store.Get("name", r)        if err != nil {            // Raise HTTP 500            return        }        // We'll assume you're storing the userID in the cookie|server session        // upon login elsewhere.        id := session.Values["userID"]        // Probably returns a *yourapp.User        user, err := db.GetUser(id)        if err != nil {            // Raise HTTP 500            return        }        if user == nil {            http.Error(w, http.StatusText(http.StatusUnauthorized), http.StatusUnauthorized)            // Don't forget these 'naked' returns - if you miss one, your             // handler will keep processing beyond the error and result in            // unintended side effects            return        }        // Further checks here - i.e. checking user.Active == true, etc.        // The userID matches one in the DB, so let's proceed        h.ServeHTTP(w, r)    }    return http.HandlerFunc(fn)}// And in your router - assuming just vanilla net/httphttp.Handle("/", RequireAuth(yourHandlerFunc))http.Handle("/", RequireAuth(someOtherHandler))// Note that using gorilla/mux or goji can help give you "subrouters" so you// don't have to wrap every single route with your middleware (messy, error prone)我还建议您阅读有关 Go 中间件1组合2 的一些内容,这将对您将来有所帮助。如果您想调用自定义错误页面,只需编写一个处理程序 - 例如UnauthorizedHandler,满足 http.Handler 并且只是调用UnauthorizedHandler.ServeHTTP(w, r)而不是http.Error沿途调用。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go