Skip to content
Merged
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
34 changes: 26 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,27 +13,45 @@ Use cookie as session, base on [secure cookie](https://github.com/go-http-utils/
* Multiple sessions per request, even using different backends.
* Interfaces and infrastructure for custom session backends: sessions from
different stores can be retrieved and batch-saved using a common API.
* User can customize own session with different field that don't require type assertion and cast

##Installation
```go
go get github.com/go-http-utils/cookie-session
```
##Examples
```go
go run cookiesession/main.go
go run example/main.go
```
##Usage
```go
store := sessions.NewCookieStore([]string{"key"})
// Session is custom by user's business
type Session struct {
*sessions.Meta `json:"-"`
UserID string `json:"userId"`
Name string `json:"name"`
Authed int64 `json:"authed"`
}

func (s *Session) Save() error {
return s.SaveIt(s)
}
func main() {
SessionName := "Sess"
SessionKeys := []string{"keyxxx"}

store := sessions.New()

handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
session, _ := store.Get(sessionkey, w, r)
if val, ok := session.Values["name"]; ok {
println(val)
} else {
session.Values["name"] = "mushroom"
session := &Session{Meta: &sessions.Meta{}}
store.Load(SessionName, session, cookie.New(w, r, SessionKeys))
if session.UserID == "" {
session.UserID = "x"
session.Name = "y"
session.Authed = 1
}
session.Save()
})
```
##Store Implementations
##Other Store Implementations
- https://github.com/mushroomsir/session-redis -Redis
51 changes: 0 additions & 51 deletions cookiesession/main.go

This file was deleted.

76 changes: 31 additions & 45 deletions cookiestore.go
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
package sessions

import (
"net/http"
"reflect"

"github.com/go-http-utils/cookie"
)
import "github.com/go-http-utils/cookie"

// Options stores configuration for a session or session store.
//
Expand All @@ -21,59 +16,50 @@ type Options struct {
HTTPOnly bool
}

// NewCookieStore an CookieStore instance
func NewCookieStore(keys []string, options ...*Options) (store *CookieStore) {
store = &CookieStore{keys: keys}
if len(options) > 0 {
store.options = options[0]
var (
lastSessionValue = "lastSessionValue"
)

// New an CookieStore instance
func New(options ...*Options) (store *CookieStore) {
opts := &cookie.Options{
Path: "/",
HTTPOnly: true,
Signed: true,
MaxAge: 24 * 60 * 60,
}
if len(keys) > 0 && len(keys[0]) > 0 {
store.signed = true
if len(options) > 0 && options[0] != nil {
temp := options[0]
opts.Path = temp.Path
opts.Domain = temp.Domain
opts.MaxAge = temp.MaxAge
opts.Secure = temp.Secure
opts.HTTPOnly = temp.HTTPOnly
}
store = &CookieStore{opts}
return
}

// CookieStore stores sessions using secure cookies.
type CookieStore struct {
options *Options
keys []string
signed bool
opts *cookie.Options
}

// Get a session instance by name and any kind of stores
func (c *CookieStore) Get(name string, w http.ResponseWriter, r *http.Request) (session *Session, err error) {
cookie := cookie.New(w, r, c.keys)
session = NewSession(name, c, w, r)
val, _ := cookie.Get(name, c.signed)
// Load a session by name and any kind of stores
func (c *CookieStore) Load(name string, session Sessions, cookie *cookie.Cookies) error {
val, err := cookie.Get(name, c.opts.Signed)
if val != "" {
Decode(val, &session.Values)
Decode(val, &session)
}
session.AddCache("cookie", cookie)
session.AddCache("lastvalue", session.Values)
return
session.Init(name, val, cookie, c, val)
return err
}

// Save session to Response's cookie
func (c *CookieStore) Save(w http.ResponseWriter, r *http.Request, session *Session) (err error) {
if reflect.DeepEqual(session.GetCache("lastvalue"), session.Values) {
return
}
opts := &cookie.Options{
Path: "/",
HTTPOnly: true,
Signed: c.signed,
MaxAge: 24 * 60 * 60,
}
if c.options != nil {
opts.Path = c.options.Path
opts.Domain = c.options.Domain
opts.MaxAge = c.options.MaxAge
opts.Secure = c.options.Secure
opts.HTTPOnly = c.options.HTTPOnly
}
val, err := Encode(session.Values)
if err == nil {
session.GetCache("cookie").(*cookie.Cookies).Set(session.Name(), val, opts)
func (c *CookieStore) Save(session Sessions) (err error) {
val, err := Encode(session)
if err == nil && session.IsChanged(val) {
session.GetCookie().Set(session.GetName(), val, c.opts)
}
return
}
66 changes: 66 additions & 0 deletions example/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
package main

import (
"net/http"
"net/http/httptest"

"github.com/go-http-utils/cookie"
"github.com/go-http-utils/cookie-session"
)

// Session ...
type Session struct {
*sessions.Meta `json:"-"`
UserID string `json:"userId"`
Name string `json:"name"`
Authed int64 `json:"authed"`
}

// Save ...
func (s *Session) Save() error {
return s.GetStore().Save(s)
}

func main() {
SessionName := "Sess"
SessionKeys := []string{"keyxxx"}

recorder := httptest.NewRecorder()
req, _ := http.NewRequest("GET", "/", nil)

store := sessions.New()
handler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {

session := &Session{Meta: &sessions.Meta{}}
store.Load(SessionName, session, cookie.New(w, r, SessionKeys))
if session.UserID == "" {
session.UserID = "x"
session.Name = "y"
session.Authed = 1
}
session.Save()
})
handler.ServeHTTP(recorder, req)

//======reuse=====
req, _ = http.NewRequest("GET", "/", nil)
migrateCookies(recorder, req)

store = sessions.New()
handler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
session := &Session{Meta: &sessions.Meta{}}
store.Load(SessionName, session, cookie.New(w, r, SessionKeys))

println(session.UserID)
println(session.Name)
println(session.Authed)

session.Save()
})
handler.ServeHTTP(recorder, req)
}
func migrateCookies(recorder *httptest.ResponseRecorder, req *http.Request) {
for _, cookie := range recorder.Result().Cookies() {
req.AddCookie(cookie)
}
}
Loading