基于 gorilla/sessions 在 Go 语言中管理 Session

Go语言精选

共 2945字,需浏览 6分钟

 ·

2020-08-19 22:15

Go 语言官方提供的 http 包虽然对 HTTP 编程提供了丰富的 API,但是没有提供官方的 Session 实现。如果在 Web 应用中使用到了 Session,需要自行去实现(就像在线论坛这个入门项目中所做的那样),或者使用第三方工具包,比如 gorilla/sessions,这里我们以后者为例演示如何通过它在 Go Web 应用中启动和管理 Session。

gorilla/sessions 内置了基于 Cookie 和文件系统作为存储引擎的 Session 实现,此外,还为其他后端自定义 Session 存储驱动提供了底层接口(比如 Memcache、Redis、MySQL、MongoDB、PostgreSQL、CockroachDB 等,更多第三方驱动实现请参考项目官方文档)。

下面我们基于 gorilla/sessions 通过 Session 来实现一个简单的计数器,这里我们使用 Cookie 作为存储器。新建一个 counter 目录,运行 go mod init demo/counter 进行模块初始化 :

然后在该目录下编写计数器服务端实现代码 main.go

package main

import (
    "github.com/gorilla/sessions"
    "html/template"
    "log"
    "net/http"
    "os"
)

// 初始化存储器(基于 Cookie)
var store = sessions.NewCookieStore([]byte(os.Getenv("SESSION_KEY)")))

func counter(w http.ResponseWriter, r *http.Request)  {
    session, _ := store.Get(r, "GOSESSID")
    count := session.Values["count"];
    if count == nil {
        session.Values["count"] = 1
    } else {
        session.Values["count"] = count.(int) + 1
    }
    err := session.Save(r, w)
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    t, _ := template.ParseFiles("counter.gtpl")
    w.Header().Set("Content-Type""text/html")
    t.Execute(w, session.Values["count"])
}

func main()  {
    http.HandleFunc("/counter", counter)
    err := http.ListenAndServe(":8888"nil)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

运行 go mod tidy 自动下载依赖。

通过上述源码可以看到,要基于 gorilla/sessions 管理 Session,首先要初始化一个 Session 存储器,这里我们使用 sessions.NewCookieStore 创建一个基于 Cookie 的 Session 存储器,并且通过系统变量传入 SESSION_KEY 进行认证。

在具体某个 Web 路由处理器方法中使用 Session(这里是处理 /counter 路由的 counter  处理器方法),可以通过 store.Get 方法获取或者创建一个新的 Session 对象(通过 GOSESSID 进行标识),然后我们试图通过 session.Values["count"] 从这个 Session 对象上获取存储在其中的 count 变量值,如果值为空,将其初始化为 1,否则在原来的基础上加 1,从而实现计数器的功能。最后,我们通过 session.Save 方法保存 Session 更改。

注:session.Values 是一个字典结构(map[interface{}]interface{}),所以可以向其中添加任意多个键值对存储信息。

我们通过 counter.gtpl 作为页面模板来渲染这个计数器视图,并且将 Session 中存储的 count 值传递给该视图模板。

counter 目录下创建这个 counter.gtpl 并编写一段简单的视图模板代码:

<h1>当前计数器的值:{{ . }}h1>

运行 go run main.go 启动计数器服务(不要忘了传递 SESSION_KEY 系统变量):

然后在浏览器中就可以通过 http://localhost:8888/counter 访问这个计数器了:

每次刷新页面,计数器的值都会 +1:

打开浏览器开发者工具,在 Application | Storage | Cookies 中可以看到存储在 Cookie 中的 Session 信息(加密过),其默认有效期是 1 个月:

如果我们删除这个 Cookie,则 Session 数据会清空,计数器归零,刷新页面,计数器的值恢复成 1:

我们还可以将上述 Cookie 存储调整为文件存储:

// 初始化存储器
var store = sessions.NewFilesystemStore("session", []byte(os.Getenv("SESSION_KEY)")))

counter 目录下新建一个 session 子目录,重启服务,访问 http://localhost:8888/counter,可以看到 session 目录下现在会创建对应的 Session 文件:

由于 Session 本身需要依赖 Cookie 存储 Session ID,所以在开发者工具中依然会包含名为 GOSESSID 的 Cookie 信息。

你还可以通过存储对象提供的 API 设置 Session 有效期,通过 Session 对象设置一次性消息(Flash Message),更多细节,请查看 gorilla/sessions 包底层源码。

(全文完)



推荐阅读



学习交流 Go 语言,扫码回复「进群」即可


站长 polarisxu

自己的原创文章

不限于 Go 技术

职场和创业经验


Go语言中文网

每天为你

分享 Go 知识

Go爱好者值得关注


浏览 82
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报