我正在使用Go开发RESTful API,但由于应用程序配置,身份验证等原因,我有很多全局变量。
由于受欢迎的推荐,我正在使用Julien Schmidt的httprouter,我正在寻找避免全局变量的可行方法。
以下是一些代码。
我正在使用中间件来验证使用gorrila / securecookie的用户。
func AuthMiddleware(handler httprouter.Handle, isLoggedIn bool) httprouter.Handle {
return func(w http.ResponseWriter, r *http.Request, ps httprouter.Params) {if isLoggedIn {
currUser, err := GetCurrentUser(r)
if currUser.Username != "" {
handler(w, r, ps)
return
}
responseWriter(w, false, "User not logged in", nil)
return
}
handler(w, r, ps)
}
}
在此之后,我希望能够在请求转发到的处理程序中使用currUser对象,而不是再次调用GetCurrentUser
func foobar(w http.ResponseWriter, _ *http.Request, _ httprouter.Params) {
var currQuestion CurrQuestions
err = Db.db.Raw("SELECT * FROM users WHERE U.user_id = ?", currUser.UserID).Find(&currQuestion).Error
if err != nil {
responseWriter(w, false, "Internal Server Error", "")
return
}
responseWriter(w, true, "", GameData{})
}
答案 0 :(得分:0)
您可以使用上下文包。存储在上下文中的值只能在当前控制器中访问。在您的中间件(最后)执行以下操作:
ctx := context.WithValue(r.Context(), "User", user)
r = r.WithContext(ctx)
handler(w, r, ps)
现在您可以在处理程序中获取此值:
user, ok := r.Context().Value("User").(<type of your user struct>)
字符串“User”是用于保存值的键。你可以随意改变它,但const是个好主意。
如果ok
为true
,则已提取用户且类型正确。如果ok
为false
,则表示用户未设置或类型错误。