会话管理(Session)

中间件 session 为 Macaron 实例 提供了会话管理的功能。

下载安装

  1. go get github.com/go-macaron/session

使用示例

  1. import (
  2. "github.com/go-macaron/session"
  3. "gopkg.in/macaron.v1"
  4. )
  5.  
  6. func main() {
  7. m := macaron.Classic()
  8. m.Use(macaron.Renderer())
  9. m.Use(session.Sessioner())
  10.  
  11. m.Get("/", func(sess session.Store) string {
  12. sess.Set("session", "session middleware")
  13. return sess.Get("session").(string)
  14. })
  15.  
  16. m.Get("/signup", func(ctx *macaron.Context, f *session.Flash) {
  17. f.Success("yes!!!")
  18. f.Error("opps...")
  19. f.Info("aha?!")
  20. f.Warning("Just be careful.")
  21. ctx.HTML(200, "signup")
  22. })
  23.  
  24. m.Run()
  25. }
  1. <!-- templates/signup.tmpl -->
  2. <h2>{{.Flash.SuccessMsg}}</h2>
  3. <h2>{{.Flash.ErrorMsg}}</h2>
  4. <h2>{{.Flash.InfoMsg}}</h2>
  5. <h2>{{.Flash.WarningMsg}}</h2>

Pongo2

如果您正在使用 pongo2 作为应用的模板引擎,则需要对 HTML 进行如下修改:

  1. <!-- templates/signup.tmpl -->
  2. <h2>{{Flash.SuccessMsg}}</h2>
  3. <h2>{{Flash.ErrorMsg}}</h2>
  4. <h2>{{Flash.InfoMsg}}</h2>
  5. <h2>{{Flash.WarningMsg}}</h2>

将 Flash 输出到当前响应

默认情况下,Flash 的数据只会在相对应会话的下一个响应中使用,但函数 SuccessErrorInfoWarning 均接受第二个参数来指示是否在当前响应输出数据:

  1. // ...
  2. f.Success("yes!!!", true)
  3. f.Error("opps...", true)
  4. f.Info("aha?!", true)
  5. f.Warning("Just be careful.", true)
  6. // ...

但是请注意,不管您选择什么时候输出 Flash 的数据,它都只能够被使用一次。

自定义选项

该服务允许接受一个参数来进行自定义选项(session.Options):

  1. //...
  2. m.Use(session.Sessioner(session.Options{
  3. // 提供器的名称,默认为 "memory"
  4. Provider: "memory",
  5. // 提供器的配置,根据提供器而不同
  6. ProviderConfig: "",
  7. // 用于存放会话 ID 的 Cookie 名称,默认为 "MacaronSession"
  8. CookieName: "MacaronSession",
  9. // Cookie 储存路径,默认为 "/"
  10. CookiePath: "/",
  11. // GC 执行时间间隔,默认为 3600 秒
  12. Gclifetime: 3600,
  13. // 最大生存时间,默认和 GC 执行时间间隔相同
  14. Maxlifetime: 3600,
  15. // 仅限使用 HTTPS,默认为 false
  16. Secure: false,
  17. // Cookie 生存时间,默认为 0 秒
  18. CookieLifeTime: 0,
  19. // Cookie 储存域名,默认为空
  20. Domain: "",
  21. // 会话 ID 长度,默认为 16 位
  22. IDLength: 16,
  23. // 配置分区名称,默认为 "session"
  24. Section: "session",
  25. }))
  26. //...

提供器

目前有 9 款内置的提供器,除了 内存文件 提供器外,您都必须显式导入其它提供器的驱动。

以下为提供器的基本用法:

内存

  1. //...
  2. m.Use(session.Sessioner())
  3. //...

文件

  1. //...
  2. m.Use(session.Sessioner(session.Options{
  3. Provider: "file",
  4. ProviderConfig: "data/sessions",
  5. }))
  6. //...

Redis

  1. import _ "github.com/go-macaron/session/redis"
  2.  
  3. //...
  4. m.Use(session.Sessioner(session.Options{
  5. Provider: "redis",
  6. // e.g.: network=tcp,addr=127.0.0.1:6379,password=macaron,db=0,pool_size=100,idle_timeout=180,prefix=session:
  7. ProviderConfig: "addr=127.0.0.1:6379,password=macaron",
  8. }))
  9. //...

Memcache

  1. import _ "github.com/go-macaron/session/memcache"
  2.  
  3. //...
  4. m.Use(session.Sessioner(session.Options{
  5. Provider: "memcache",
  6. // e.g.: 127.0.0.1:9090;127.0.0.1:9091
  7. ProviderConfig: "127.0.0.1:9090",
  8. }))
  9. //...

PostgreSQL

可以使用以下 SQL 语句创建数据库(请确保 key 的长度和您设置的 Options.IDLength 一致):

  1. CREATE TABLE session (
  2. key CHAR(16) NOT NULL,
  3. data BYTEA,
  4. expiry INTEGER NOT NULL,
  5. PRIMARY KEY (key)
  6. );
  1. import _ "github.com/go-macaron/session/postgres"
  2.  
  3. //...
  4. m.Use(session.Sessioner(session.Options{
  5. Provider: "postgres",
  6. ProviderConfig: "user=a password=b dbname=c sslmode=disable",
  7. }))
  8. //...

MySQL

可以使用以下 SQL 语句创建数据库:

  1. CREATE TABLE `session` (
  2. `key` CHAR(16) NOT NULL,
  3. `data` BLOB,
  4. `expiry` INT(11) UNSIGNED NOT NULL,
  5. PRIMARY KEY (`key`)
  6. ) ENGINE=MyISAM DEFAULT CHARSET=utf8;
  1. import _ "github.com/go-macaron/session/mysql"
  2.  
  3. //...
  4. m.Use(session.Sessioner(session.Options{
  5. Provider: "mysql",
  6. ProviderConfig: "username:password@protocol(address)/dbname?param=value",
  7. }))
  8. //...

Couchbase

  1. import _ "github.com/go-macaron/session/couchbase"
  2.  
  3. //...
  4. m.Use(session.Sessioner(session.Options{
  5. Provider: "couchbase",
  6. ProviderConfig: "username:password@protocol(address)/dbname?param=value",
  7. }))
  8. //...

Ledis

  1. import _ "github.com/go-macaron/session/ledis"
  2.  
  3. //...
  4. m.Use(session.Sessioner(session.Options{
  5. Provider: "ledis",
  6. ProviderConfig: "data_dir=./app.db,db=0",
  7. }))
  8. //...

Nodb

  1. import _ "github.com/go-macaron/session/nodb"
  2.  
  3. //...
  4. m.Use(session.Sessioner(session.Options{
  5. Provider: "nodb",
  6. ProviderConfig: "data/cache.db",
  7. }))
  8. //...

实现提供器接口

如果您需要实现自己的会话存储和提供器,可以通过实现下面两个接口实现,同时还可以将 内存 提供器作为学习案例。

  1. // RawStore is the interface that operates the session data.
  2. type RawStore interface {
  3. // Set sets value to given key in session.
  4. Set(key, value interface{}) error
  5. // Get gets value by given key in session.
  6. Get(key interface{}) interface{}
  7. // Delete deletes a key from session.
  8. Delete(key interface{}) error
  9. // ID returns current session ID.
  10. ID() string
  11. // Release releases session resource and save data to provider.
  12. Release() error
  13. // Flush deletes all session data.
  14. Flush() error
  15. }
  16.  
  17. // Provider is the interface that provides session manipulations.
  18. type Provider interface {
  19. // Init initializes session provider.
  20. Init(gclifetime int64, config string) error
  21. // Read returns raw session store by session ID.
  22. Read(sid string) (RawStore, error)
  23. // Exist returns true if session with given ID exists.
  24. Exist(sid string) bool
  25. // Destory deletes a session by session ID.
  26. Destory(sid string) error
  27. // Regenerate regenerates a session store from old session ID to new one.
  28. Regenerate(oldsid, sid string) (RawStore, error)
  29. // Count counts and returns number of sessions.
  30. Count() int
  31. // GC calls GC to clean expired sessions.
  32. GC()
  33. }