Browse Source

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

Jakob Borg 2 years ago
parent
commit
8f1b0df74b
1 changed files with 32 additions and 22 deletions
  1. 32 22
      lib/api/api_auth.go

+ 32 - 22
lib/api/api_auth.go

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