59 lines
1.2 KiB
Go
59 lines
1.2 KiB
Go
package middleware
|
|
|
|
import (
|
|
"net/http"
|
|
"sync"
|
|
)
|
|
|
|
// In-memory session store — swap for Redis/DB in production
|
|
var (
|
|
sessionStore = make(map[string]bool)
|
|
mu sync.RWMutex
|
|
)
|
|
|
|
// RegisterSession adds a token to the store (call this after login)
|
|
func RegisterSession(token string) {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
sessionStore[token] = true
|
|
}
|
|
|
|
// RevokeSession removes a token (call this on logout)
|
|
func RevokeSession(token string) {
|
|
mu.Lock()
|
|
defer mu.Unlock()
|
|
delete(sessionStore, token)
|
|
}
|
|
|
|
// RequireSession is the middleware — wraps any handler that needs auth
|
|
func RequireSession(next http.Handler) http.Handler {
|
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
cookie, err := r.Cookie("session")
|
|
if err != nil {
|
|
// No cookie at all
|
|
http.Redirect(w, r, "/login", http.StatusSeeOther)
|
|
return
|
|
}
|
|
|
|
mu.RLock()
|
|
valid := sessionStore[cookie.Value]
|
|
mu.RUnlock()
|
|
|
|
if !valid {
|
|
// Cookie exists but token is unknown/expired
|
|
http.SetCookie(w, &http.Cookie{
|
|
Name: "session",
|
|
Value: "",
|
|
Path: "/",
|
|
HttpOnly: true,
|
|
Secure: true,
|
|
MaxAge: -1, // delete it
|
|
})
|
|
http.Redirect(w, r, "/login", http.StatusSeeOther)
|
|
return
|
|
}
|
|
|
|
next.ServeHTTP(w, r)
|
|
})
|
|
}
|