go - 如何使用 julien schmidt 的路由器避免 Go 中的全局变量?

标签 go

我正在使用 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{})
}

最佳答案

您可以使用上下文包。存储在上下文中的值只能在当前 Controller 中访问。在您的中间件中(最后)执行以下操作:

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 是个好主意。

如果 oktrue,则用户已被提取并且是正确的类型。如果 okfalse,则用户未设置或类型错误。

关于go - 如何使用 julien schmidt 的路由器避免 Go 中的全局变量?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49180023/

相关文章:

go - The Go Language 有 SAML 库吗?

c - 函数名称和原型(prototype)中的斜线和点?

xml - 正确的结构布局以在 go 中解析 xml

go - vim-go、模块和 GoRename

string - 如何在 Go 中使用反射设置一个指向字符串的结构成员

go - 尝试评估丢失的嵌套键时,Helm 图表失败并显示 "nil pointer evaluating interface {}"

node.js - 隐蔽 Node.js 加密 HMAC 到 Go-lang HMAC 加密

go-smtp,无法通过 gmail 发送电子邮件,收到 EOF

function - 在 Go 模板中,我可以让 Parse 工作但不能让 ParseFiles 以类似的方式工作。为什么?

map - 如何在 Go 中创建 map[[16]byte][]string?