[Admin UI] Login not possible due to securecookie error (#7374)
* [Admin UI] Login not possible due to securecookie error * avoid 404 favicon * Update weed/admin/dash/auth_middleware.go Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com> * address comments * avoid variable over shadowing * log session save error --------- Co-authored-by: gemini-code-assist[bot] <176961590+gemini-code-assist[bot]@users.noreply.github.com>
This commit is contained in:
@@ -191,31 +191,7 @@ func startAdminServer(ctx context.Context, options AdminOptions) error {
|
||||
r := gin.New()
|
||||
r.Use(gin.Logger(), gin.Recovery())
|
||||
|
||||
// Session store - always auto-generate session key
|
||||
sessionKeyBytes := make([]byte, 32)
|
||||
_, err := rand.Read(sessionKeyBytes)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to generate session key: %w", err)
|
||||
}
|
||||
store := cookie.NewStore(sessionKeyBytes)
|
||||
|
||||
// Configure session options to ensure cookies are properly saved
|
||||
store.Options(sessions.Options{
|
||||
Path: "/",
|
||||
MaxAge: 3600 * 24, // 24 hours
|
||||
})
|
||||
|
||||
r.Use(sessions.Sessions("admin-session", store))
|
||||
|
||||
// Static files - serve from embedded filesystem
|
||||
staticFS, err := admin.GetStaticFS()
|
||||
if err != nil {
|
||||
log.Printf("Warning: Failed to load embedded static files: %v", err)
|
||||
} else {
|
||||
r.StaticFS("/static", http.FS(staticFS))
|
||||
}
|
||||
|
||||
// Create data directory if specified
|
||||
// Create data directory first if specified (needed for session key storage)
|
||||
var dataDir string
|
||||
if *options.dataDir != "" {
|
||||
// Expand tilde (~) to home directory
|
||||
@@ -236,6 +212,35 @@ func startAdminServer(ctx context.Context, options AdminOptions) error {
|
||||
fmt.Printf("Data directory created/verified: %s\n", dataDir)
|
||||
}
|
||||
|
||||
// Detect TLS configuration to set Secure cookie flag
|
||||
cookieSecure := viper.GetString("https.admin.key") != ""
|
||||
|
||||
// Session store - load or generate session key
|
||||
sessionKeyBytes, err := loadOrGenerateSessionKey(dataDir)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to get session key: %w", err)
|
||||
}
|
||||
store := cookie.NewStore(sessionKeyBytes)
|
||||
|
||||
// Configure session options to ensure cookies are properly saved
|
||||
store.Options(sessions.Options{
|
||||
Path: "/",
|
||||
MaxAge: 3600 * 24, // 24 hours
|
||||
HttpOnly: true, // Prevent JavaScript access
|
||||
Secure: cookieSecure, // Set based on actual TLS configuration
|
||||
SameSite: http.SameSiteLaxMode,
|
||||
})
|
||||
|
||||
r.Use(sessions.Sessions("admin-session", store))
|
||||
|
||||
// Static files - serve from embedded filesystem
|
||||
staticFS, err := admin.GetStaticFS()
|
||||
if err != nil {
|
||||
log.Printf("Warning: Failed to load embedded static files: %v", err)
|
||||
} else {
|
||||
r.StaticFS("/static", http.FS(staticFS))
|
||||
}
|
||||
|
||||
// Create admin server
|
||||
adminServer := dash.NewAdminServer(*options.masters, nil, dataDir)
|
||||
|
||||
@@ -331,6 +336,46 @@ func GetAdminOptions() *AdminOptions {
|
||||
return &AdminOptions{}
|
||||
}
|
||||
|
||||
// loadOrGenerateSessionKey loads an existing session key from dataDir or generates a new one
|
||||
func loadOrGenerateSessionKey(dataDir string) ([]byte, error) {
|
||||
const sessionKeyLength = 32
|
||||
if dataDir == "" {
|
||||
// No persistence, generate random key
|
||||
log.Println("No dataDir specified, generating ephemeral session key")
|
||||
key := make([]byte, sessionKeyLength)
|
||||
_, err := rand.Read(key)
|
||||
return key, err
|
||||
}
|
||||
|
||||
sessionKeyPath := filepath.Join(dataDir, ".session_key")
|
||||
|
||||
// Try to load existing key
|
||||
if data, err := os.ReadFile(sessionKeyPath); err == nil {
|
||||
if len(data) == sessionKeyLength {
|
||||
log.Printf("Loaded persisted session key from %s", sessionKeyPath)
|
||||
return data, nil
|
||||
}
|
||||
log.Printf("Warning: Invalid session key file (expected %d bytes, got %d), generating new key", sessionKeyLength, len(data))
|
||||
} else if !os.IsNotExist(err) {
|
||||
log.Printf("Warning: Failed to read session key from %s: %v. A new key will be generated.", sessionKeyPath, err)
|
||||
}
|
||||
|
||||
// Generate new key
|
||||
key := make([]byte, sessionKeyLength)
|
||||
if _, err := rand.Read(key); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Save key for future use
|
||||
if err := os.WriteFile(sessionKeyPath, key, 0600); err != nil {
|
||||
log.Printf("Warning: Failed to persist session key: %v", err)
|
||||
} else {
|
||||
log.Printf("Generated and persisted new session key to %s", sessionKeyPath)
|
||||
}
|
||||
|
||||
return key, nil
|
||||
}
|
||||
|
||||
// expandHomeDir expands the tilde (~) in a path to the user's home directory
|
||||
func expandHomeDir(path string) (string, error) {
|
||||
if path == "" {
|
||||
|
||||
Reference in New Issue
Block a user