对某些处理请求的用户进行身份验证
Authenticate users on certain handle requests
是否有更有效的方法来验证某些处理请求的用户?现在我正在调用一个函数来根据请求令牌进行身份验证,但我正在为每个句柄函数执行此操作。
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")
}
我还希望将来能够实现用户角色,以便根据安全权限选择不同的路径是否可用。
最有效的方法是什么?
你真的不需要中间件。您可以通过将处理程序包装到通用身份验证函数来实现这一点。
看看下面的代码,我认为它会满足您的需求。
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", handler)
grant 函数所做的基本上是将您的处理程序作为参数,如果一切顺利,grant 将以与 http.HandleFunc 相同的方式执行您的处理程序。
fn(w, r)
如果身份验证失败,grant 将 return 出错并且永远不会执行您的处理程序。
是否有更有效的方法来验证某些处理请求的用户?现在我正在调用一个函数来根据请求令牌进行身份验证,但我正在为每个句柄函数执行此操作。
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")
}
我还希望将来能够实现用户角色,以便根据安全权限选择不同的路径是否可用。
最有效的方法是什么?
你真的不需要中间件。您可以通过将处理程序包装到通用身份验证函数来实现这一点。 看看下面的代码,我认为它会满足您的需求。
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", handler)
grant 函数所做的基本上是将您的处理程序作为参数,如果一切顺利,grant 将以与 http.HandleFunc 相同的方式执行您的处理程序。
fn(w, r)
如果身份验证失败,grant 将 return 出错并且永远不会执行您的处理程序。