Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow to set alternative cookie name #3

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 44 additions & 15 deletions session.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,12 +47,15 @@ import (
"time"
)

const cookieName = "session"
const defaultCookieName = "session"

var ErrCookieTooLong = errors.New("session: cookie length greater than 4096 bytes")
var ErrCookieTooLong = errors.New("cookie length greater than 4096 bytes")

// Session holds the configuration settings that you want to use for your sessions.
type Session struct {
// Name of the cookie key
CookieName string

// Domain sets the 'Domain' attribute on the session cookie. By default
// it will be set to the domain name that the cookie was issued from.
Domain string
Expand Down Expand Up @@ -98,26 +101,40 @@ type Session struct {
keys [][32]byte
}

type Params struct {
// Required.
// The Key parameter is the secret you want to use to authenticate and encrypt
// session cookies. It should be exactly 32 bytes long.
Key []byte
// Optional. The OldKeys parameter can be used to provide an arbitrary
// number of old Keys. This can be used to ensure that valid cookies continue
// to work correctly after key rotation.
OldKeys [][]byte
// Optional. Default is `session`.
// An alternative cookie name can be used for resolving collisions with
// the other packages which use the cookie of the same name, or for overcoming
// the 4096 bytes value limit by creating several cookie storages.
CookieName string
}

// New initializes a new Session object to hold the configuration settings for
// your sessions.
//
// The key parameter is the secret you want to use to authenticate and encrypt
// session cookies. It should be exactly 32 bytes long.
//
// Optionally, the variadic oldKeys parameter can be used to provide an arbitrary
// number of old Keys. This can be used to ensure that valid cookies continue
// to work correctly after key rotation.
func New(key []byte, oldKeys ...[]byte) *Session {
func NewWithParams(params Params) *Session {
if len(params.Key) == 0 {
panic(`parameter Key must be provided`)
}

keys := make([][32]byte, 1)
copy(keys[0][:], key)
copy(keys[0][:], params.Key)

for _, key := range oldKeys {
for _, key := range params.OldKeys {
var newKey [32]byte
copy(newKey[:], key)
keys = append(keys, newKey)
}

return &Session{
CookieName: params.CookieName,
Domain: "",
HttpOnly: true,
Lifetime: 24 * time.Hour,
Expand All @@ -130,6 +147,18 @@ func New(key []byte, oldKeys ...[]byte) *Session {
}
}

// Simplified Session initilizer.
// The same as NewWithParams(), with default 'session' cookie name.
func New(key []byte, oldKeys ...[]byte) *Session {
params := Params{
Key: key,
OldKeys: oldKeys,
CookieName: defaultCookieName,
}

return NewWithParams(params)
}

// Enable is middleware which loads and saves session data to and from the
// session cookie. You should use this middleware to wrap ALL handlers which
// need to access to the session data. A common way to do this is to wrap your
Expand Down Expand Up @@ -168,7 +197,7 @@ func (s *Session) Enable(next http.Handler) http.Handler {
}

func (s *Session) load(r *http.Request) (*cache, error) {
cookie, err := r.Cookie(cookieName)
cookie, err := r.Cookie(s.CookieName)
if err == http.ErrNoCookie {
return newCache(s.Lifetime), nil
} else if err != nil {
Expand Down Expand Up @@ -200,7 +229,7 @@ func (s *Session) save(w http.ResponseWriter, c *cache) error {

if c.destroyed {
http.SetCookie(w, &http.Cookie{
Name: cookieName,
Name: s.CookieName,
Value: "",
Path: s.Path,
Domain: s.Domain,
Expand All @@ -219,7 +248,7 @@ func (s *Session) save(w http.ResponseWriter, c *cache) error {
}

cookie := &http.Cookie{
Name: cookieName,
Name: s.CookieName,
Value: token,
Path: s.Path,
Domain: s.Domain,
Expand Down
8 changes: 4 additions & 4 deletions session_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,8 +70,8 @@ func TestDestroy(t *testing.T) {

_, cookie := testRequest(t, s.Enable(h), "")

if !strings.HasPrefix(cookie, fmt.Sprintf("%s=;", cookieName)) {
t.Errorf("got %q: expected prefix %q", cookie, fmt.Sprintf("%s=;", cookieName))
if !strings.HasPrefix(cookie, fmt.Sprintf("%s=;", s.CookieName)) {
t.Errorf("got %q: expected prefix %q", cookie, fmt.Sprintf("%s=;", s.CookieName))
}
if !strings.Contains(cookie, "Expires=Thu, 01 Jan 1970 00:00:01 GMT") {
t.Errorf("got %q: expected to contain %q", cookie, "Expires=Thu, 01 Jan 1970 00:00:01 GMT")
Expand Down Expand Up @@ -121,7 +121,7 @@ func TestInvalidCookies(t *testing.T) {
s := New([]byte("u46IpCV9y5Vlur8YvODJEhgOY8m9JVE4"))

cookie := &http.Cookie{
Name: cookieName,
Name: s.CookieName,
Value: "",
}

Expand All @@ -135,7 +135,7 @@ func TestInvalidCookies(t *testing.T) {
}

cookie = &http.Cookie{
Name: cookieName,
Name: s.CookieName,
Value: "`",
}

Expand Down