21

我是 Go 语言 (Golang) 的新手,我正在编写一个基于 Web 的应用程序。我想使用会话变量,例如 PHP 中的那种(从一页到下一页可用的变量,并且对于用户会话是唯一的)。Go中有类似的东西吗?如果没有,我将如何自己实施它们?或者有什么替代方法?

4

3 回答 3

17

你可能想看看大猩猩。它具有此处记录的会话支持。

除此之外,或者可能是其他 Web 工具包之一,您将不得不自己动手。

可能的解决方案可能是:

  • 每个用户会话的 goroutine 将会话变量存储在内存中。
  • 将变量存储在会话 cookie 中。
  • 使用数据库存储用户会话数据。

我将把每一个的实现细节留给读者。

于 2012-06-07T03:41:16.910 回答
6

如果您只需要没有完整的 Web 工具包的会话支持,这是一个替代方案。

https://github.com/bpowers/seshcookie

于 2013-06-27T02:37:06.283 回答
5

这是另一种选择(披露:我是作者):

https://github.com/icza/session

引用其文档:


该软件包提供了易于使用、可扩展且安全的会话实施和管理。可以在 godoc.org 中找到包文档:

https://godoc.org/github.com/icza/session

这“只是”一个 HTTP 会话实现和管理,您可以按原样使用它,也可以与任何现有的 Go web 工具包和框架一起使用。

概述

包中有 3 个主要参与者

  • Session是(HTTP)会话接口。我们可以使用它来存储和从中检索常量和变量属性。
  • Store是一个会话存储接口,负责存储会话并使它们可以在服务器端通过它们的 ID 进行检索。
  • Manager是一个会话管理器接口,负责Session从(传入的)HTTP 请求中获取 a,并将 a 添加Session到 HTTP 响应以让客户端知道会话。AManager有一个支持Store,负责管理Session服务器端的值。

这个包的播放器由接口表示,并为所有这些播放器提供了各种实现。您不受所提供的实现的约束,请随时为任何玩家提供您自己的实现。

用法

用法再简单不过了。要获取与http.Request关联的当前会话:

sess := session.Get(r)
if sess == nil {
    // No session (yet)
} else {
    // We have a session, use it
}

要创建一个新会话(例如成功登录)并将其添加到http.ResponseWriter(让客户端知道该会话):

sess := session.NewSession()
session.Add(sess, w)

让我们看看更高级的会话创建:让我们提供一个常量属性(会话的生命周期)和一个初始的可变属性:

sess := session.NewSessionOptions(&session.SessOptions{
    CAttrs: map[string]interface{}{"UserName": userName},
    Attrs:  map[string]interface{}{"Count": 1},
})

并访问这些属性并更改 的值"Count"

userName := sess.CAttr("UserName")
count := sess.Attr("Count").(int) // Type assertion, you might wanna check if it succeeds
sess.SetAttr("Count", count+1)    // Increment count

(当然,变量属性也可以在以后添加Session.SetAttr(),而不仅仅是在会话创建时。)

要删除会话(例如注销时):

session.Remove(sess, w)

查看会话演示应用程序,它显示了所有这些操作。

谷歌应用引擎支持

该软件包提供对 Google App Engine (GAE) 平台的支持。

文档不包括它(由于+build appengine构建约束),但它是:gae_memcache_store.go

该实现将会话存储在 Memcache 中,并将会话保存到 Datastore 作为备份,以防数据从 Memcache 中删除。此行为是可选的,可以完全禁用 Datastore。您还可以选择是同步(在同一个 goroutine 中)还是异步(在另一个 goroutine 中)保存到 Datastore,从而缩短响应时间。

我们可以使用NewMemcacheStore()NewMemcacheStoreOptions()函数来创建一个会话存储实现,它将会话存储在 GAE 的 Memcache 中。需要注意的是,由于访问 Memcache 依赖于绑定到 的 Appengine Context http.Request,因此返回的 Store 只能用于请求的生命周期!请注意,当 Store 关闭时,Store 会自动“刷新”从中访问的会话,因此在请求结束时关闭 Store 非常重要;这通常通过关闭您将存储传递到的会话管理器来完成(最好使用 defer 语句)。

所以在每个请求处理中,我们必须使用新的 Store 创建一个新的会话管理器,我们可以使用会话管理器来执行与会话相关的任务,如下所示:

ctx := appengine.NewContext(r)
sessmgr := session.NewCookieManager(session.NewMemcacheStore(ctx))
defer sessmgr.Close() // This will ensure changes made to the session are auto-saved
                      // in Memcache (and optionally in the Datastore).

sess := sessmgr.Get(r) // Get current session
if sess != nil {
    // Session exists, do something with it.
    ctx.Infof("Count: %v", sess.Attr("Count"))
} else {
    // No session yet, let's create one and add it:
    sess = session.NewSession()
    sess.SetAttr("Count", 1)
    sessmgr.Add(sess, w)
}

过期的会话不会自动从数据存储中删除。为了删除过期的会话,包提供了一个PurgeExpiredSessFromDSFunc()返回http.HandlerFunc. 建议将返回的处理函数注册到一个路径,然后可以将其定义为定期调用的 cron 作业,例如每 30 分钟左右(您的选择)。由于 cron 处理程序可能运行长达 10 分钟,因此返回的处理程序将在 8 分钟处停止以安全完成,即使有更多过期、未删除的会话也是如此。可以这样注册:

http.HandleFunc("/demo/purge", session.PurgeExpiredSessFromDSFunc(""))

查看显示如何使用它的 GAE 会话演示应用程序。 演示的cron.yaml文件显示了如何定义 cron 作业以清除过期会话。

查看GAE 会话演示应用程序,它展示了如何在实际中使用它。

于 2016-02-09T12:28:51.997 回答