allow multi auth

This commit is contained in:
2026-06-07 14:36:39 +02:00
parent 8000df8bb3
commit 12e3694b76
2 changed files with 26 additions and 15 deletions
+23 -12
View File
@@ -8,13 +8,14 @@ import (
"io" "io"
"log" "log"
"net/http" "net/http"
"slices"
"sync" "sync"
) )
type ApiHandler struct { type ApiHandler struct {
db *Database db *Database
mutex sync.RWMutex mutex sync.RWMutex
authToken *string authTokens []string
} }
const authTokenCookieName = "auth-token" const authTokenCookieName = "auth-token"
@@ -22,6 +23,14 @@ const isAuthorizedContextKey = "is-authorized"
const contentTypeHeaderKey = "Content-Type" const contentTypeHeaderKey = "Content-Type"
const JsonMimeType = "application/json" const JsonMimeType = "application/json"
func MakeApiHandler(db *Database) ApiHandler {
return ApiHandler{
db: db,
mutex: sync.RWMutex{},
authTokens: make([]string, 0),
}
}
func (h *ApiHandler) ServeLoginPost(writer http.ResponseWriter, request *http.Request) { func (h *ApiHandler) ServeLoginPost(writer http.ResponseWriter, request *http.Request) {
if !HasContentType(request, JsonMimeType) { if !HasContentType(request, JsonMimeType) {
WriteError(writer, http.StatusBadRequest, "expected json body", nil) WriteError(writer, http.StatusBadRequest, "expected json body", nil)
@@ -64,7 +73,7 @@ func (h *ApiHandler) ServeLoginPost(writer http.ResponseWriter, request *http.Re
authToken := hex.EncodeToString(rawAuthToken) authToken := hex.EncodeToString(rawAuthToken)
h.mutex.Lock() h.mutex.Lock()
h.authToken = &authToken h.authTokens = append(h.authTokens, authToken)
h.mutex.Unlock() h.mutex.Unlock()
cookie := http.Cookie{} cookie := http.Cookie{}
@@ -81,19 +90,21 @@ func (h *ApiHandler) ServeLoginPost(writer http.ResponseWriter, request *http.Re
func (h *ApiHandler) ServeLogoutPost(writer http.ResponseWriter, request *http.Request) { func (h *ApiHandler) ServeLogoutPost(writer http.ResponseWriter, request *http.Request) {
cookie, _ := request.Cookie(authTokenCookieName) cookie, _ := request.Cookie(authTokenCookieName)
if cookie != nil {
cookie := http.Cookie{}
cookie.Name = authTokenCookieName
cookie.Value = ""
cookie.Secure = true
cookie.HttpOnly = true
http.SetCookie(writer, &cookie)
}
h.mutex.Lock() h.mutex.Lock()
h.authToken = nil index := slices.Index(h.authTokens, cookie.Value)
if index >= 0 {
slices.Delete(h.authTokens, index, index+1)
}
h.mutex.Unlock() h.mutex.Unlock()
newCookie := http.Cookie{}
newCookie.Name = authTokenCookieName
newCookie.Value = ""
newCookie.Secure = true
newCookie.HttpOnly = true
http.SetCookie(writer, &newCookie)
WriteResponse(writer, http.StatusOK, map[string]interface{}{}) WriteResponse(writer, http.StatusOK, map[string]interface{}{})
log.Printf("successful logout from '%s'", request.RemoteAddr) log.Printf("successful logout from '%s'", request.RemoteAddr)
@@ -105,7 +116,7 @@ func (h *ApiHandler) ProcessAuth(next http.Handler, required bool) http.Handler
cookie, _ := request.Cookie(authTokenCookieName) cookie, _ := request.Cookie(authTokenCookieName)
if cookie != nil { if cookie != nil {
h.mutex.RLock() h.mutex.RLock()
isAuthorized = h.authToken != nil && *h.authToken == cookie.Value isAuthorized = slices.Contains(h.authTokens, cookie.Value)
h.mutex.RUnlock() h.mutex.RUnlock()
} }
+1 -1
View File
@@ -41,7 +41,7 @@ func main() {
} }
defer db.Close() defer db.Close()
apiHandler := &ApiHandler{db: db} apiHandler := MakeApiHandler(db)
mux := http.NewServeMux() mux := http.NewServeMux()
mux.Handle("/", http.FileServer(HtmlDir{http.Dir(frontendPath)})) mux.Handle("/", http.FileServer(HtmlDir{http.Dir(frontendPath)}))