@@ -9,39 +9,41 @@ Most session libraries are highly opinionated and hard-wired to work with `net/h
99## Features
10101 . Framework/network library agnostic.
11112 . Simple API and with support for primitive data types. Complex types can be stored using own encoding/decoding.
12- 3 . Pre-built redis/postgres/in-memory stores that can be separately installed.
12+ 3 . Pre-built redis/postgres/in-memory/securecookie stores that can be separately installed.
13134 . Multiple session instances with custom handlers and different backend stores.
1414
1515## Installation
1616Install ` simplesessions ` and all [ available stores] ( /stores ) .
1717
1818``` shell
19- go get -u github.com/vividvilla/simplesessions
19+ go get -u github.com/vividvilla/simplesessions/v3
2020
21- # Install the requrired store: memory|goredis|redis|postgres
22- go get -u github.com/vividvilla/simplesessions/stores/goredis
21+ # Install the requrired store: memory|redis|postgres|securecookie
22+ go get -u github.com/vividvilla/simplesessions/v3/stores/redis
23+ go get -u github.com/vividvilla/simplesessions/v3/stores/postgres
2324```
2425
2526# Stores
2627Sessions can be stored to any backend by implementing the [ store] ( /store.go ) interface. The following stores are bundled.
2728
28- * [ in-memory] ( /stores/memory )
2929* [ redis] ( /stores/redis )
30+ * [ postgres] ( /stores/postgres )
31+ * [ in-memory] ( /stores/memory )
3032* [ secure cookie] ( /stores/securecookie )
3133
3234# Usage
3335Check the [ examples] ( /examples ) directory for complete examples.
3436
3537## Connecting a store
36- Stores can be registered to a session instance by using ` Use ` method.
38+ Stores can be registered to a session instance by using ` Use ` method. Check individual [ Stores ] ( #stores ) docs for more details.
3739
3840``` go
3941sess := simplesessions.New (simplesessions.Options {})
40- sess.UseStore (memory .New ())
42+ sess.UseStore (store .New ())
4143```
4244
4345## Connecting an HTTP handler
44- Any HTTP library can be connected to simplesessions by registering the ` RegisterGetCookie() ` and ` RegisterSetCookie ()` callbacks . The below example shows a simple ` net/http ` usecase. Another example showing ` fasthttp ` can be found [ here] ( /examples ) .
46+ Any HTTP library can be connected to simplesessions by registering the get and set cookie hooks using ` SetCookieHooks ()` . The below example shows a simple ` net/http ` usecase. Another example showing ` fasthttp ` can be found [ here] ( /examples ) .
4547
4648``` go
4749var sessMan *simplesessions.Manager
@@ -81,61 +83,104 @@ func setCookie(cookie *http.Cookie, w interface{}) error {
8183func handler (w http .ResponseWriter , r *http .Request ) {
8284 // Use method `Acquire` to acquire a session before you access the session.
8385 // Acquire takes read, write interface and context respectively.
84- // Read interface sent to callback registered with `RegisterGetCookie`
85- // and write interface is sent to callback registered with `RegisterWriteCookie`
86+ // Read interface sent to callback registered with get cookie hook
87+ // and write interface is sent to callback registered with write cookie hook
88+ // set using `SetCookieHooks()` method.
89+ //
8690 // Optionally `context` can be sent which is usually request context where acquire
8791 // session will get previously loaded session. This is useful if you have multiple
8892 // middlewares accessing sessions. New sessions will be created in first middleware which
8993 // does `Acquire` and will be reused in other places.
90- sess , err := sessMan.Acquire (r, w, nil )
91-
92- // Use 'Set` and `Commit` to set a field for session.
93- // 'Set` ideally doesn't persist the value to store unless method `Commit` is called.
94- // But note that its up to the store you are using to decide to
95- // persist data only on `commit` or persist on `Set` itself.
96- // Stores like redis, db etc should persist on `Commit` while in-memory does on `Set`.
97- // No matter what store you use its better to explicitly
98- // call `Commit` method when you set all the values.
94+ //
95+ // If `Options.EnableAutoCreate` is set to True then if session doesn't exist it will
96+ // be immediately created and returned. Bydefault its set to False so if session doesn't
97+ // exist then `ErrInvalidSession` error is returned.
98+ sess , err := sessMan.Acquire (nil , r, w)
99+
100+ // If session doesn't exist then create new session.
101+ // In a traditional login flow you can create a new session once user completes the login flow.
102+ if err == simplesessions.ErrInvalidSession {
103+ sess, err = sessMan.NewSession (r, w)
104+ }
105+
106+ // Use 'Set` or `SetMulti` to set a field for session.
99107 err = sess.Set (" somekey" , " somevalue" )
100- err = sess.Set (" someotherkey" , 10 )
101- err = sess.Commit ()
108+ err = sess.SetMulti (map [string ]interface {}{
109+ " k1" : " v1" ,
110+ " k2" : " v2" ,
111+ })
102112
103113 // Use `Get` method to get a field from current session. The result will be an interface
104114 // so you can use helper methods like
105115 // `String', `Int`, `Int64`, `UInt64`, `Float64`, `Bytes`, `Bool`.
106116 val , err := sess.String (sess.Get (" somekey" ))
117+ fmt.Println (" val=" , val)
107118
108119 // Use `GetAll` to get map of all fields from session.
109120 // The result is map of string and interface you can use helper methods to type cast it.
110- val , err := sess.GetAll ()
121+ all , err := sess.GetAll ()
122+ fmt.Println (" all=" , all)
111123
112124 // Use `GetMulti` to get values for given fields from session.
113125 // The result is map of string and interface you can use helper methods to type cast it.
114126 // If key is not there then store should ideally send `nil` value for given key.
115- val , err := sess.GetMulti (" somekey" , " someotherkey" )
127+ vals , err := sess.GetMulti (" somekey" , " someotherkey" )
128+ fmt.Println (" vals=" , vals)
116129
117130 // Use `Delete` to delete a field from session.
118- err := sess.Delete (" somekey" )
131+ err = sess.Delete (" somekey" )
132+
133+ // Use `Clear` to empty the session but to keep the session alive.
134+ err = sess.Clear ()
119135
120- // Use `Clear ` to clear session from store.
121- err : = sess.Clear ()
136+ // Use `Destroy ` to clear session from store and cookie .
137+ err = sess.Destroy ()
122138
123139 fmt.Fprintf (w, " success" )
124140}
125141
126142func main () {
127143 // Create a session manager with custom options like cookie name,
128144 // cookie domain, is secure cookie etc. Check `Options` struct for more options.
129- sessMan := simplesessions.New (simplesessions.Options {})
145+ sessMan := simplesessions.New (simplesessions.Options {
146+ // If set to true then `Acquire()` method will create new session instead of throwing
147+ // `ErrInvalidSession` when the session doesn't exist. By default its set to false.
148+ EnableAutoCreate: false ,
149+ Cookie: simplesessions.CookieOptions {
150+ // Name sets http cookie name. This is also sent as cookie name in `GetCookie` callback.
151+ Name: " session" ,
152+ // Domain sets hostname for the cookie. Domain specifies allowed hosts to receive the cookie.
153+ Domain: " example.com" ,
154+ // Path sets path for the cookie. Path indicates a URL path that must exist in the requested URL in order to send the cookie header.
155+ Path: " /" ,
156+ // IsSecure marks the cookie as secure cookie (only sent in HTTPS).
157+ IsSecure: true ,
158+ // IsHTTPOnly marks the cookie as http only cookie. JS won't be able to access the cookie so prevents XSS attacks.
159+ IsHTTPOnly: true ,
160+ // SameSite sets allows you to declare if your cookie should be restricted to a first-party or same-site context.
161+ SameSite: http.SameSiteDefaultMode ,
162+ // Expires sets absolute expiration date and time for the cookie.
163+ // If both Expires and MaxAge are sent then MaxAge takes precedence over Expires.
164+ // Cookies without a Max-age or Expires attribute – are deleted when the current session ends
165+ // and some browsers use session restoring when restarting. This can cause session cookies to last indefinitely.
166+ Expires: time.Now ().Add (time.Hour * 24 ),
167+ // Sets the cookie's expiration in seconds from the current time, internally its rounder off to nearest seconds.
168+ // If both Expires and MaxAge are sent then MaxAge takes precedence over Expires.
169+ // Cookies without a Max-age or Expires attribute – are deleted when the current session ends
170+ // and some browsers use session restoring when restarting. This can cause session cookies to last indefinitely.
171+ MaxAge: time.Hour * 24 ,
172+ },
173+ })
174+
130175 // Create a new store instance and attach to session manager
131176 sessMan.UseStore (memory.New ())
132- // Register callbacks for read and write cookie
177+ // Register callbacks for read and write cookie.
133178 // Get cookie callback should get cookie based on cookie name and
134179 // sent back in net/http cookie format.
135- sessMan.RegisterGetCookie (getCookie)
136180 // Set cookie callback should set cookie it received for received cookie name.
137- sessMan.RegisterSetCookie ( setCookie)
181+ sessMan.SetCookieHooks (getCookie, setCookie)
138182
139- http.HandleFunc (" /set" , handler)
183+ // Initialize the handler.
184+ http.HandleFunc (" /" , handler)
140185}
141186```
0 commit comments