lib/api: Improve cookie handling (fixes #9208) (#9214)

This commit is contained in:
Jakob Borg 2023-11-13 20:37:29 +01:00
parent 07ad2db503
commit 53123c0b01
1 changed files with 32 additions and 22 deletions

View File

@ -85,14 +85,19 @@ func basicAuthAndSessionMiddleware(cookieName string, guiCfg config.GUIConfigura
return return
} }
cookie, err := r.Cookie(cookieName) for _, cookie := range r.Cookies() {
if err == nil && cookie != nil { // We iterate here since there may, historically, be multiple
sessionsMut.Lock() // cookies with the same name but different path. Any "old" ones
_, ok := sessions[cookie.Value] // won't match an existing session and will be ignored, then
sessionsMut.Unlock() // later removed on logout or when timing out.
if ok { if cookie.Name == cookieName {
next.ServeHTTP(w, r) sessionsMut.Lock()
return _, ok := sessions[cookie.Value]
sessionsMut.Unlock()
if ok {
next.ServeHTTP(w, r)
return
}
} }
} }
@ -198,21 +203,26 @@ func createSession(cookieName string, username string, guiCfg config.GUIConfigur
func handleLogout(cookieName string) http.Handler { func handleLogout(cookieName string) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
cookie, err := r.Cookie(cookieName) for _, cookie := range r.Cookies() {
if err == nil && cookie != nil { // We iterate here since there may, historically, be multiple
sessionsMut.Lock() // cookies with the same name but different path. We drop them
delete(sessions, cookie.Value) // all.
sessionsMut.Unlock() if cookie.Name == cookieName {
} sessionsMut.Lock()
// else: If there is no session cookie, that's also a successful logout in terms of user experience. delete(sessions, cookie.Value)
sessionsMut.Unlock()
// Delete the cookie
http.SetCookie(w, &http.Cookie{
Name: cookieName,
Value: "",
MaxAge: -1,
Secure: cookie.Secure,
Path: cookie.Path,
})
}
}
http.SetCookie(w, &http.Cookie{
Name: cookieName,
Value: "",
MaxAge: -1,
Secure: true,
Path: "/",
})
w.WriteHeader(http.StatusNoContent) w.WriteHeader(http.StatusNoContent)
}) })
} }