Sign cookies in the Redis Session store

This commit is contained in:
Joel Speed 2019-05-15 17:20:32 +01:00 committed by Brian Van Klaveren
parent 2c566a5f5b
commit b255ed56ef

View File

@ -71,11 +71,9 @@ func (store *SessionStore) Save(rw http.ResponseWriter, req *http.Request, s *se
return err return err
} }
ticketCookie := cookies.MakeCookieFromOptions( ticketCookie := store.makeCookie(
req, req,
store.CookieOptions.CookieName,
ticketString, ticketString,
store.CookieOptions,
store.CookieOptions.CookieExpire, store.CookieOptions.CookieExpire,
s.CreatedAt, s.CreatedAt,
) )
@ -91,8 +89,12 @@ func (store *SessionStore) Load(req *http.Request) (*sessions.SessionState, erro
if err != nil { if err != nil {
return nil, fmt.Errorf("error loading session: %s", err) return nil, fmt.Errorf("error loading session: %s", err)
} }
// No cookie validation necessary
session, err := store.LoadSessionFromString(requestCookie.Value) val, _, ok := cookie.Validate(requestCookie, store.CookieOptions.CookieSecret, store.CookieOptions.CookieExpire)
if !ok {
return nil, fmt.Errorf("Cookie Signature not valid")
}
session, err := store.LoadSessionFromString(val)
if err != nil { if err != nil {
return nil, fmt.Errorf("error loading session: %s", err) return nil, fmt.Errorf("error loading session: %s", err)
} }
@ -132,12 +134,15 @@ func (store *SessionStore) LoadSessionFromString(value string) (*sessions.Sessio
func (store *SessionStore) Clear(rw http.ResponseWriter, req *http.Request) error { func (store *SessionStore) Clear(rw http.ResponseWriter, req *http.Request) error {
requestCookie, _ := req.Cookie(store.CookieOptions.CookieName) requestCookie, _ := req.Cookie(store.CookieOptions.CookieName)
val, _, ok := cookie.Validate(requestCookie, store.CookieOptions.CookieSecret, store.CookieOptions.CookieExpire)
if !ok {
return fmt.Errorf("Cookie Signature not valid")
}
// We go ahead and clear the cookie first, always. // We go ahead and clear the cookie first, always.
clearCookie := cookies.MakeCookieFromOptions( clearCookie := store.makeCookie(
req, req,
store.CookieOptions.CookieName,
"", "",
store.CookieOptions,
time.Hour*-1, time.Hour*-1,
time.Now(), time.Now(),
) )
@ -145,10 +150,9 @@ func (store *SessionStore) Clear(rw http.ResponseWriter, req *http.Request) erro
// We only return an error if we had an issue with redis // We only return an error if we had an issue with redis
// If there's an issue decoding the ticket, ignore it // If there's an issue decoding the ticket, ignore it
ticket, _ := decodeTicket(store.CookieOptions.CookieName, requestCookie.Value) ticket, _ := decodeTicket(store.CookieOptions.CookieName, val)
if ticket != nil { if ticket != nil {
deleted, err := store.Client.Del(ticket.asHandle(store.CookieOptions.CookieName)).Result() _, err := store.Client.Del(ticket.asHandle(store.CookieOptions.CookieName)).Result()
fmt.Println("delted %n", deleted)
if err != nil { if err != nil {
return fmt.Errorf("error clearing cookie from redis: %s", err) return fmt.Errorf("error clearing cookie from redis: %s", err)
} }
@ -156,6 +160,21 @@ func (store *SessionStore) Clear(rw http.ResponseWriter, req *http.Request) erro
return nil return nil
} }
// makeCookie makes a cookie, signing the value if present
func (store *SessionStore) makeCookie(req *http.Request, value string, expires time.Duration, now time.Time) *http.Cookie {
if value != "" {
value = cookie.SignedValue(store.CookieOptions.CookieSecret, store.CookieOptions.CookieName, value, now)
}
return cookies.MakeCookieFromOptions(
req,
store.CookieOptions.CookieName,
value,
store.CookieOptions,
expires,
now,
)
}
func (store *SessionStore) storeValue(value string, expiresOn time.Time, requestCookie *http.Cookie) (string, error) { func (store *SessionStore) storeValue(value string, expiresOn time.Time, requestCookie *http.Cookie) (string, error) {
var ticket *TicketData var ticket *TicketData
if requestCookie != nil { if requestCookie != nil {