Skip to content
Snippets Groups Projects
cookie_middleware.go 1.17 KiB
Newer Older
package auth

import (
	"context"
	"net/http"

	"github.com/rs/zerolog"
)

// CookieMiddleware reads the authentication cookie and add a 'auth-claims' key
// in the request context. The cookie must be unique, if more than one cookie
// is found, an error is logged and a 401 error is returned.
func CookieMiddleware[T any, PT interface {
	*T
	Claims
}](options *TokenOptions) func(http.Handler) http.Handler {
	cookieName := options.cookieBasename + "-auth"

	return func(h http.Handler) http.Handler {
		return http.HandlerFunc(func(rw http.ResponseWriter, r *http.Request) {
			ctx := r.Context()
			log := zerolog.Ctx(ctx)

			cookies := r.CookiesNamed(cookieName)
			if len(cookies) > 1 {
				log.Warn().Int("count", len(cookies)).Msg("multiple auth cookies found")
				rw.WriteHeader(http.StatusUnauthorized)
				return
			}

			if len(cookies) == 0 {
				h.ServeHTTP(rw, r)
				return
			}

			claims := PT(new(T))
			if err := options.ParseToken(cookies[0].Value, claims); err != nil {
				log.Err(err).Str("cookie-name", cookieName).Msg("could not parse auth cookie token")
			}
			r = r.WithContext(
				context.WithValue(ctx, contextAuthClaims, claims),