diff options
Diffstat (limited to 'internal')
| -rw-r--r-- | internal/handlers/auth.go | 23 | ||||
| -rw-r--r-- | internal/handlers/middleware.go | 37 | ||||
| -rw-r--r-- | internal/models/auth.go | 5 | 
3 files changed, 53 insertions, 12 deletions
| diff --git a/internal/handlers/auth.go b/internal/handlers/auth.go index 5ec1c80..e7eca50 100644 --- a/internal/handlers/auth.go +++ b/internal/handlers/auth.go @@ -3,6 +3,9 @@ package handlers  import (  	"apjournal/internal/models"  	"apjournal/pkg/utils" +	"crypto/hmac" +	"crypto/sha256" +	"encoding/base64"  	"encoding/json"  	"html/template"  	"net/http" @@ -61,6 +64,7 @@ func (h *Handlers) HandleLogin(w http.ResponseWriter, r *http.Request) {  }  func (h *Handlers) makeCookie(username string, remote string) (*http.Cookie, error) { +	// secret  	// Create a new random session token  	// sessionToken := xid.New().String()  	sessionToken := "token" @@ -70,10 +74,18 @@ func (h *Handlers) makeCookie(username string, remote string) (*http.Cookie, err  		Username: username,  		Expiry:   expiresAt,  	} -	// TODO: write session to db +	cookieName := "session_token" +	// hmac to protect cookies +	hm := hmac.New(sha256.New, []byte(h.cfg.CookieSecret)) +	hm.Write([]byte(cookieName)) +	hm.Write([]byte(sessionToken)) +	signature := hm.Sum(nil) +	// b64 enc to avoid non-ascii +	cookieValue := base64.URLEncoding.EncodeToString([]byte( +		string(signature) + sessionToken))  	cookie := &http.Cookie{ -		Name:     "session_token", -		Value:    sessionToken, +		Name:     cookieName, +		Value:    cookieValue,  		Secure:   true,  		HttpOnly: true,  		SameSite: http.SameSiteNoneMode, @@ -86,7 +98,10 @@ func (h *Handlers) makeCookie(username string, remote string) (*http.Cookie, err  		cookie.Domain = "192.168.0.101"  	}  	// set ctx? -	// c.Set("username", username) +	// set user in session +	if err := h.cacheSetSession(sessionToken, session); err != nil { +		return nil, err +	}  	return cookie, nil  } diff --git a/internal/handlers/middleware.go b/internal/handlers/middleware.go index 28ccdbc..8b871a2 100644 --- a/internal/handlers/middleware.go +++ b/internal/handlers/middleware.go @@ -2,24 +2,51 @@ package handlers  import (  	"context" +	"crypto/hmac" +	"crypto/sha256" +	"encoding/base64"  	"errors"  	"net/http"  )  func (h *Handlers) GetSession(next http.Handler) http.Handler {  	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { -		sessionCookie, err := r.Cookie("session_token") +		cookieName := "session_token" +		sessionCookie, err := r.Cookie(cookieName)  		if err != nil {  			msg := "auth failed; failed to get session token from cookies"  			h.log.Debug(msg, "error", err)  			next.ServeHTTP(w, r)  			return  		} -		sessionToken := "" -		if sessionCookie.Value == "" { -			sessionToken = sessionCookie.Value +		cookieValueB, err := base64.URLEncoding. +			DecodeString(sessionCookie.Value) +		if err != nil { +			msg := "auth failed; failed to decode b64 cookie" +			h.log.Debug(msg, "error", err) +			next.ServeHTTP(w, r) +			return +		} +		cookieValue := string(cookieValueB) +		if len(cookieValue) < sha256.Size { +			h.log.Warn("small cookie", "size", len(cookieValue)) +			next.ServeHTTP(w, r) +			return +		} +		// Split apart the signature and original cookie value. +		signature := cookieValue[:sha256.Size] +		sessionToken := cookieValue[sha256.Size:] +		//verify signature +		mac := hmac.New(sha256.New, []byte(h.cfg.CookieSecret)) +		mac.Write([]byte(cookieName)) +		mac.Write([]byte(sessionToken)) +		expectedSignature := mac.Sum(nil) +		if !hmac.Equal([]byte(signature), expectedSignature) { +			h.log.Debug("cookie with an invalid sign") +			next.ServeHTTP(w, r) +			return  		} -		userSession, err := h.cacheGetSession(sessionCookie.Value) +		userSession, err := h.cacheGetSession(sessionToken)  		if err != nil {  			msg := "auth failed; session does not exists"  			err = errors.New(msg) diff --git a/internal/models/auth.go b/internal/models/auth.go index 5dadf8a..9964cd5 100644 --- a/internal/models/auth.go +++ b/internal/models/auth.go @@ -6,9 +6,8 @@ import (  // each session contains the username of the user and the time at which it expires  type Session struct { -	Username    string -	CurrentRoom string -	Expiry      time.Time +	Username string +	Expiry   time.Time  }  // we'll use this method later to determine if the session has expired | 
