一 写在开始的简介和弯路(用处不大,可直接看第二部分哦

Why session?
Session会在一定时间内保存在服务器上,相比Cookie更安全…更值得一提的当然是session的密钥key,实现session的加密功能

刚开始写session的时候,走了点“弯路”,自己跟着封装sessions的思路去封装了一个sessions包,其实可以直接用现成封装好的sessions包来使用sessions功能。
在这里插入图片描述
代码大纲:
在这里插入图片描述


一条华华丽丽的分割线,把上面没啥用的话割去(其实就是告诉大家不需要自己写session包)
然后下面就是对sessions包的使用咯(划重点哦)!!!

二 session库的准备工作

主要调用的包:
https://github.com/gin-contrib/sessions
同时需要依赖包:
https://github.com/gorilla/sessions
其实当时报错缺包是如下几种:
在这里插入图片描述
下图是我的golang目录结构:
在这里插入图片描述
安装包的方法其实不难,总结如下:
1、在命令行中go get github.com/gin-contrib/sessions(但是其实下载时有点慢)
2、在git bashgit clone https://github.com/gin-contrib/sessions.git(我一般这样用的很方便的操作)
3、有时候克隆不完整/失败,就直接点,上github下载下来就OK了(其实蛮实用的万能方法)

三 实现session的代码逻辑

逻辑很简单,要保持登录状态嘛,在login的路由中,登录成功之后加上设置保存session的代码,但是创建cookie store密钥及使用中间件的时候,代码放在main()或全局中哦

四 session库的代码实现方法

1 设置全局变量store(划重点:全局)
var store = cookie.NewStore([]byte("secret"))

eg. 我是将main和router分开的,所以像这样就可以:
在这里插入图片描述

2 在路由中使用中间件调用store
r := gin.Default()
r.Use(sessions.Sessions("sessionid", store))
3 初始化sessions
session := sessions.Default(c)
4 设置sessions的相关参数
option := sessions.Options{MaxAge: 3600}
session.Options(option)
5 生成sessions并保存(记得一定要Save的!)
session.Set("sessionid", username)
err := session.Save()
6 服务器端检查一下是否成功
if err != nil {
	fmt.Println("Fail to save session")
} else {
	fmt.Println("Succeed to save session")
}
v := session.Get("sessionid")
fmt.Println("sessionid:", v)

注意:这里session.Get在终端打印出来的sessionid是未加密字符串!但是实际上对外保存的字符串是通过了key加密后的结果!下面是postman的测试结果:
在这里插入图片描述
在这里插入图片描述
看到那堆乱七八糟的字符串了吗?那就对啦⭐,因为它是字符串"www"对应的加密字符串~

7 获取sessions值
session := sessions.Default(c)
v := session.Get("sessionid")
fmt.Println("sessionid:", v)
8 响应头的设置
c.Header("Access-Control-Allow-Origin", "*")
c.Header("Access-Control-Allow-Credentials", "true")

五 另外提一点点

其实github上的官方教程例子很好代码也简洁,也是很实用的教程,可以仔细看看(用法并不复杂,但是需要实践去测试怎么正确使用,只要掌握就很简单了)
用了sessions包以后代码也就变得很简单很多很多很多x100啦

【1】请求调试工具:Postman
【2】附上官方链接: https://github.com/gin-contrib/sessions
【3】net/httpCookie的调用: 【Golang】Cookie保持会话状态的实现
【4】Cookie/Session机制详解: Cookie/Session机制详解

六、补充

上面的写法固然没有问题,这里补充另一种写法(2020.7.19)

1 生成session
func SaveSession(w http.ResponseWriter, r *http.Request) {
    // 获取一个session对象,session-name是session的名字
    session, err := store.Get(r, "sessionID")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    // 在session中存储值
    session.Values["sessionID"] = userId
    // 保存更改
    session.Save(r, w)
}
2 获取session
func GetSession(w http.ResponseWriter, r *http.Request) {
    session, err := store.Get(r, "sessionID")
    if err != nil {
        http.Error(w, err.Error(), http.StatusInternalServerError)
        return
    }
    id := session.Values["sessionID"]
    fmt.Println("sessionID", id)
}

如上函数获取到的id是一个接口型参数,不能直接当作string返回

3 设置session
session.Options.MaxAge = -1
//负数即是直接删除session 正数即是设置time
session.Save(r, w)

如果我们使用gin框架,那么替换如下:

r ---> c.Request
w ---> c.Writer
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐