feat(module,auth): dynamically define authentication cookie domain

This commit is contained in:
wpetit 2023-04-05 15:19:22 +02:00
parent 84c8fd51f6
commit 006f13bc7b
2 changed files with 49 additions and 24 deletions

View File

@ -30,12 +30,12 @@ func init() {
} }
type LocalHandler struct { type LocalHandler struct {
router chi.Router router chi.Router
algo jwa.KeyAlgorithm algo jwa.KeyAlgorithm
key jwk.Key key jwk.Key
cookieDomain string getCookieDomain GetCookieDomainFunc
cookieDuration time.Duration cookieDuration time.Duration
accounts map[string]LocalAccount accounts map[string]LocalAccount
} }
func (h *LocalHandler) initRouter(prefix string) { func (h *LocalHandler) initRouter(prefix string) {
@ -118,10 +118,18 @@ func (h *LocalHandler) handleForm(w http.ResponseWriter, r *http.Request) {
return return
} }
cookieDomain, err := h.getCookieDomain(r)
if err != nil {
logger.Error(ctx, "could not retrieve cookie domain", logger.E(errors.WithStack(err)))
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
cookie := http.Cookie{ cookie := http.Cookie{
Name: auth.CookieName, Name: auth.CookieName,
Value: string(token), Value: string(token),
Domain: h.cookieDomain, Domain: cookieDomain,
HttpOnly: false, HttpOnly: false,
Expires: time.Now().Add(h.cookieDuration), Expires: time.Now().Add(h.cookieDuration),
Path: "/", Path: "/",
@ -133,12 +141,20 @@ func (h *LocalHandler) handleForm(w http.ResponseWriter, r *http.Request) {
} }
func (h *LocalHandler) handleLogout(w http.ResponseWriter, r *http.Request) { func (h *LocalHandler) handleLogout(w http.ResponseWriter, r *http.Request) {
cookieDomain, err := h.getCookieDomain(r)
if err != nil {
logger.Error(r.Context(), "could not retrieve cookie domain", logger.E(errors.WithStack(err)))
http.Error(w, http.StatusText(http.StatusInternalServerError), http.StatusInternalServerError)
return
}
http.SetCookie(w, &http.Cookie{ http.SetCookie(w, &http.Cookie{
Name: auth.CookieName, Name: auth.CookieName,
Value: "", Value: "",
HttpOnly: false, HttpOnly: false,
Expires: time.Unix(0, 0), Expires: time.Unix(0, 0),
Domain: h.cookieDomain, Domain: cookieDomain,
Path: "/", Path: "/",
}) })
@ -170,11 +186,11 @@ func NewLocalHandler(algo jwa.KeyAlgorithm, key jwk.Key, funcs ...LocalHandlerOp
} }
handler := &LocalHandler{ handler := &LocalHandler{
algo: algo, algo: algo,
key: key, key: key,
accounts: toAccountsMap(opts.Accounts), accounts: toAccountsMap(opts.Accounts),
cookieDomain: opts.CookieDomain, getCookieDomain: opts.GetCookieDomain,
cookieDuration: opts.CookieDuration, cookieDuration: opts.CookieDuration,
} }
handler.initRouter(opts.RoutePrefix) handler.initRouter(opts.RoutePrefix)

View File

@ -1,22 +1,31 @@
package http package http
import "time" import (
"net/http"
"time"
)
type GetCookieDomainFunc func(r *http.Request) (string, error)
func defaultGetCookieDomain(r *http.Request) (string, error) {
return "", nil
}
type LocalHandlerOptions struct { type LocalHandlerOptions struct {
RoutePrefix string RoutePrefix string
Accounts []LocalAccount Accounts []LocalAccount
CookieDomain string GetCookieDomain GetCookieDomainFunc
CookieDuration time.Duration CookieDuration time.Duration
} }
type LocalHandlerOptionFunc func(*LocalHandlerOptions) type LocalHandlerOptionFunc func(*LocalHandlerOptions)
func defaultLocalHandlerOptions() *LocalHandlerOptions { func defaultLocalHandlerOptions() *LocalHandlerOptions {
return &LocalHandlerOptions{ return &LocalHandlerOptions{
RoutePrefix: "", RoutePrefix: "",
Accounts: make([]LocalAccount, 0), Accounts: make([]LocalAccount, 0),
CookieDomain: "", GetCookieDomain: defaultGetCookieDomain,
CookieDuration: 24 * time.Hour, CookieDuration: 24 * time.Hour,
} }
} }
@ -32,9 +41,9 @@ func WithRoutePrefix(prefix string) LocalHandlerOptionFunc {
} }
} }
func WithCookieOptions(domain string, duration time.Duration) LocalHandlerOptionFunc { func WithCookieOptions(getCookieDomain GetCookieDomainFunc, duration time.Duration) LocalHandlerOptionFunc {
return func(opts *LocalHandlerOptions) { return func(opts *LocalHandlerOptions) {
opts.CookieDomain = domain opts.GetCookieDomain = getCookieDomain
opts.CookieDuration = duration opts.CookieDuration = duration
} }
} }