项目作者: golangcollege

项目描述 :
Session management for Go 1.11+
高级语言: Go
项目地址: git://github.com/golangcollege/sessions.git
创建时间: 2018-10-21T14:32:57Z
项目社区:https://github.com/golangcollege/sessions

开源协议:MIT License

下载


Sessions GoDoc Go Report Card Build Status License

A minimalist and lightweight HTTP session cookie implementation for Go 1.11+. Session cookies are encrypted and authenticated using nacl/secretbox.

Example Usage

  1. package main
  2. import (
  3. "net/http"
  4. "time"
  5. "github.com/golangcollege/sessions"
  6. )
  7. var session *sessions.Session
  8. var secret = []byte("u46IpCV9y5Vlur8YvODJEhgOY8m9JVE4")
  9. func main() {
  10. // Initialize and configure new session instance, passing in a 32 byte
  11. // long secret key (which is used to encrypt and authenticate the
  12. // session data).
  13. session = sessions.New(secret)
  14. session.Lifetime = 3 * time.Hour
  15. mux := http.NewServeMux()
  16. mux.HandleFunc("/put", putHandler)
  17. mux.HandleFunc("/get", getHandler)
  18. // Wrap your handlers with the session middleware.
  19. http.ListenAndServe(":4000", session.Enable(mux))
  20. }
  21. func putHandler(w http.ResponseWriter, r *http.Request) {
  22. // Use the Put() method to store a new key and associated value in the
  23. // session data.
  24. session.Put(r, "msg", "Hello world")
  25. w.WriteHeader(200)
  26. }
  27. func getHandler(w http.ResponseWriter, r *http.Request) {
  28. // Use the GetString() method helper to retrieve the value associated with
  29. // a key and convert it to a string. The empty string is returned if the
  30. // key does not exist in the session data.
  31. msg := session.GetString(r, "msg")
  32. w.Write([]byte(msg))
  33. }

Configuring sessions

When setting up a session instance you can specify a mixture of options, or none at all if you’re happy with the defaults.

  1. session = sessions.New([]byte("u46IpCV9y5Vlur8YvODJEhgOY8m9JVE4"))
  2. // Domain sets the 'Domain' attribute on the session cookie. By default
  3. // it will be set to the domain name that the cookie was issued from.
  4. session.Domain = "example.org"
  5. // HttpOnly sets the 'HttpOnly' attribute on the session cookie. The
  6. // default value is true.
  7. session.HttpOnly = false
  8. // Lifetime sets the maximum length of time that a session is valid for
  9. // before it expires. The lifetime is an 'absolute expiry' which is set when
  10. // the session is first created and does not change. The default value is 24
  11. // hours.
  12. session.Lifetime = 10*time.Minute
  13. // Path sets the 'Path' attribute on the session cookie. The default value
  14. // is "/". Passing the empty string "" will result in it being set to the
  15. // path that the cookie was issued from.
  16. session.Path = "/account"
  17. // Persist sets whether the session cookie should be persistent or not
  18. // (i.e. whether it should be retained after a user closes their browser).
  19. // The default value is true, which means that the session cookie will not
  20. // be destroyed when the user closes their browser and the appropriate
  21. // 'Expires' and 'MaxAge' values will be added to the session cookie.
  22. session.Persist = false
  23. // Secure sets the 'Secure' attribute on the session cookie. The default
  24. // value is false. It's recommended that you set this to true and serve all
  25. // requests over HTTPS in production environments.
  26. session.Secure = true
  27. // SameSite controls the value of the 'SameSite' attribute on the session
  28. // cookie. By default this is set to 'SameSite=Lax'. If you want no SameSite
  29. // attribute or value in the session cookie then you should set this to 0.
  30. session.SameSite = http.SameSiteStrictMode
  31. // ErrorHandler allows you to control behaviour when an error is encountered
  32. // loading or writing the session cookie. By default the client is sent a
  33. // generic "500 Internal Server Error" response and the actual error message
  34. // is logged using the standard logger. If a custom ErrorHandler function is
  35. // provided then control will be passed to this instead.
  36. session.ErrorHandler = func(http.ResponseWriter, *http.Request, error) {
  37. log.Println(err.Error())
  38. http.Error(w, "Sorry, the application encountered an error", 500)
  39. }

Key rotation

Secret key rotation is supported. An arbitrary number of old secret keys can be provided when initializing a new session instance, like so:

  1. secretKey := []byte("Nrqe6etTZ68GymwxsgpjqwecHqyKLQrr")
  2. oldSecretKey := []byte("TSV2GUduLGYwMkVcssFrHwCHXLhfBH5e")
  3. veryOldSecretKey := []byte("mtuKkskgHwfJzzP56apvNWzrbqfKHvTB")
  4. session = sessions.New(secretKey, oldSecretKey, veryOldSecretKey)
  5. session.Lifetime = 3 * time.Hour

When a session cookie is received from a client, all secret keys are looped through to try to decode the session data. When sending the session cookie to a client the first secret key is used to encrypt the session data.

Managing session data

Adding data

  • Put() — Add a key and corresponding value to the session data.

Important: Because session data is encrypted, signed and stored in a cookie, and cookies are limited to 4096 characters in length, storing large amounts of data may result in a ErrCookieTooLong error.

Fetching data

  • Get() — Fetch the value for a given key from the session data. The returned type is interface{} so will usually need to be type asserted before use.
  • GetBool() — Fetch a bool value for a given key from the session data.
  • GetBytes() — Fetch a byte slice ([]byte) value for a given key from the session data.
  • GetFloat() — Fetch a float64 value for a given key from the session data.
  • GetInt() — Fetch a int value for a given key from the session data.
  • GetString() — Fetch a string value for a given key from the session data.
  • GetTime() — Fetch a time.Time value for a given key from the session data.

  • Pop() — Fetch the value for a given key and then delete it from the session data. The returned type is interface{} so will usually need to be type asserted before use.

  • PopBool() — Fetch a bool value for a given key and then delete it from the session data.
  • PopBytes() — Fetch a byte slice ([]byte) value for a given key and then delete it from the session data.
  • PopFloat() — Fetch a float64 value for a given key and then delete it from the session data.
  • PopInt() — Fetch a int value for a given key and then delete it from the session data.
  • PopString() — Fetch a string value for a given key and then delete it from the session data.
  • PopTime() — Fetch a time.Time value for a given key and then delete it from the session data.

Deleting data

  • Remove() — Deletes a specific key and value from the session data.
  • Destroy() — Destroy the current session. The session data is deleted from memory and the client is instructed to delete the session cookie.

Other

  • Exists() — Returns true if a given key exists in the session data.
  • Keys() — Returns a slice of all keys in the session data.

Custom data types

Behind the scenes SCS uses gob encoding to store custom data types. For this to work properly:

  • Your custom type must first be registered with the encoding/gob package.
  • The fields of your custom types must be exported.

For example:

  1. package main
  2. import (
  3. "encoding/gob"
  4. "errors"
  5. "fmt"
  6. "log"
  7. "net/http"
  8. "time"
  9. "github.com/golangcollege/sessions"
  10. )
  11. var session *sessions.Session
  12. var secret = []byte("u46IpCV9y5Vlur8YvODJEhgOY8m9JVE4")
  13. // Note that the fields on the custom type are all exported.
  14. type User struct {
  15. Name string
  16. Email string
  17. }
  18. func main() {
  19. // Register the type with the encoding/gob package.
  20. gob.Register(User{})
  21. session = sessions.New(secret)
  22. session.Lifetime = 3 * time.Hour
  23. mux := http.NewServeMux()
  24. mux.HandleFunc("/put", putHandler)
  25. mux.HandleFunc("/get", getHandler)
  26. http.ListenAndServe(":4000", session.Enable(mux))
  27. }
  28. func putHandler(w http.ResponseWriter, r *http.Request) {
  29. user := User{"Alice", "alice@example.com"}
  30. session.Put(r, "user", user)
  31. w.WriteHeader(200)
  32. }
  33. func getHandler(w http.ResponseWriter, r *http.Request) {
  34. user, ok := session.Get(r, "user").(User)
  35. if !ok {
  36. log.Println(errors.New("type assertion to User failed"))
  37. http.Error(w, http.StatusText(500), 500)
  38. return
  39. }
  40. fmt.Fprintf(w, "Name: %s, Email: %s", user.Name, user.Email)
  41. }