【发布时间】:2020-11-02 01:01:23
【问题描述】:
我还是 Go 新手……这很奇怪……
我有一个使用 Gorilla Sessions 进行身份验证的简单网络应用程序。我将会话对象 Auth 存储在 NewCookieStore 中。
如果我浏览到 /users,我的代码 302 会重定向到 /login。我登录并且它工作。我可以去 /users 然后点击 /user/1234 就好了。
如果我直接输入 /user/1234,它会正确重定向到 /login,让我登录,并且我的 UI 显示标题中的 Auth 变量。但它无法从会话中获取 Auth 对象。
如果我将 URL 展平为 /users 和 /1234,它可以正常工作...
所以它一定与范围和URI有关吗?当我转到 /user/1234 时,GetAuth 只返回 nil。但它会返回更高一级的正确对象...
保护 URI 由中间件函数完成。所以代码应该是一样的。
有人可以指出我缺少什么吗?
提前致谢
func protect(next http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
log.Println("-----------------", r.Method, r.RequestURI)
s := db.GetSession(r)
auth := db.GetAuth(s)
if !auth.Authenticated {
returnuri := r.RequestURI
s.Values["ReturnURI"] = returnuri
err := s.Save(r, w)
if err != nil {
log.Println(err)
}
http.Redirect(w, r, "/login", 302)
}
next(w, r)
}
}
...
var Store = sessions.NewCookieStore([]byte("super-secret-key"))
type Auth struct {
Username string
Authenticated bool
}
func InitSessions() {
Store.Options = &sessions.Options{
MaxAge: 60 * 5,
HttpOnly: true,
}
gob.Register(Auth{})
}
func GetSession(r *http.Request) *sessions.Session {
s, err := Store.Get(r, "user-session")
if err != nil {
log.Fatal(err)
}
return s
}
func GetAuth(s *sessions.Session) Auth {
val := s.Values["Auth"]
var auth = Auth{}
auth, ok := val.(Auth)
if !ok {
auth = Auth{Authenticated: false, Username: ""}
}
return auth
}
...
if match {
auth := db.Auth{
Username: user.Name,
Authenticated: true,
}
s.Values["Auth"] = auth
err := s.Save(r, w)
if err != nil {
log.Fatal(err)
}
http.Redirect(w, r, "/", 302)
...
r := mux.NewRouter()
r.HandleFunc("/", logged(handlers.Index))
r.HandleFunc("/signup", logged(handlers.Signup))
r.HandleFunc("/login", logged(handlers.Login))
r.HandleFunc("/logout", logged(handlers.Logout))
r.HandleFunc("/user", protect(handlers.User))
r.HandleFunc("/user/{id}", protect(handlers.User))
r.HandleFunc("/users", protect(handlers.Users))
【问题讨论】:
标签: go