Justin-刘清政的博客

go/4-Go语言框架/4-1-gin框架/6-会话控制

2020-09-16

一 Cookie的使用

测试服务端发送cookie给客户端,客户端请求时携带cookie

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
package main

import (
"fmt"
"github.com/gin-gonic/gin"
)

func main() {
// 1.创建路由
r := gin.Default()
// 服务端要给客户端cookie
r.GET("cookie", func(c *gin.Context) {
// 获取客户端是否携带cookie
cookie, err := c.Cookie("key_cookie")
if err != nil {
cookie = "NotSet"
// 给客户端设置cookie
// maxAge int, 单位为秒
// path,cookie所在目录
// domain string,域名
// secure 是否智能通过https访问
// httpOnly bool 是否允许别人通过js获取自己的cookie
c.SetCookie("key_cookie", "value_cookie", 60, "/",
"", false, true)
}
fmt.Printf("cookie的值是: %s\n", cookie)
c.SetCookie("name", "lqz", 600, "",
"", false, true)
c.String(200,"ok")

})
r.Run(":8080")
}

二 Cookie练习

  • 模拟实现权限验证中间件
    • 有2个路由,login和home
    • login用于设置cookie
    • home是访问查看信息的请求
    • 在请求home之前,先跑中间件代码,检验是否存在cookie
  • 访问home,会显示错误,因为权限校验未通过
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
package main

import (
"github.com/gin-gonic/gin"
"net/http"
)
func AuthMiddleWare() gin.HandlerFunc {
return func(c *gin.Context) {
// 获取客户端cookie并校验
if cookie, err := c.Cookie("login"); err == nil {
if cookie == "yes" {
c.Next()
return
}
}
// 返回错误
c.JSON(http.StatusUnauthorized, gin.H{"error": "err"})
// 若验证不通过,不再调用后续的函数处理
c.Abort()
return
}
}

func main() {
// 1.创建路由
r := gin.Default()
r.GET("/login", func(c *gin.Context) {
// 设置cookie
c.SetCookie("login", "yes", 60, "/",
"", false, true)
// 返回信息
c.String(200, "Login success!")
})
r.GET("/home", AuthMiddleWare(), func(c *gin.Context) {
c.JSON(200, gin.H{"data": "home"})
})
r.Run(":8080")
}

三 session

下载:go get github.com/gorilla/sessions

gorilla/sessions为自定义session后端提供cookie和文件系统session以及基础结构。

主要功能是:

  • 简单的API:将其用作设置签名(以及可选的加密)cookie的简便方法。
  • 内置的后端可将session存储在cookie或文件系统中。
  • Flash消息:一直持续读取的session值。
  • 切换session持久性(又称“记住我”)和设置其他属性的便捷方法。
  • 旋转身份验证和加密密钥的机制。
  • 每个请求有多个session,即使使用不同的后端也是如此。
  • 自定义session后端的接口和基础结构:可以使用通用API检索并批量保存来自不同商店的session。

gin框架使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package main

import (
"fmt"
"github.com/gin-gonic/gin"
"net/http"

"github.com/gorilla/sessions"
)

// 初始化一个cookie存储对象
// something-very-secret应该是一个你自己的密匙,只要不被别人知道就行
var store = sessions.NewCookieStore([]byte("asdfasdf"))

func main() {
r:=gin.New()
r.GET("/savesession", func(context *gin.Context) {
// Get a session. We're ignoring the error resulted from decoding an
// existing session: Get() always returns a session, even if empty.
session, err := store.Get(context.Request, "session-name")
if err != nil {
context.String(http.StatusInternalServerError,"出错了")
return
}

// 在session中存储值
session.Values["name"] = "lqz"
session.Values["age"] = 18
session.Values[42] = 43
// 保存更改
session.Save(context.Request, context.Writer)
context.String(200,"保存session成功")
})
r.GET("getsession", func(context *gin.Context) {
session, err := store.Get(context.Request, "session-name")
if err != nil {
context.String(http.StatusInternalServerError,"出错了")
return
}
name := session.Values["name"]
age := session.Values["age"]
count:=session.Values[42]
fmt.Println(name)
fmt.Println(age)
fmt.Println(count)
context.String(200,"查询成功")
})
r.Run()
}

net/http使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
package main

import (
"fmt"
"net/http"

"github.com/gorilla/sessions"
)

// 初始化一个cookie存储对象
// something-very-secret应该是一个你自己的密匙,只要不被别人知道就行
var store = sessions.NewCookieStore([]byte("something-very-secret"))

func main() {
http.HandleFunc("/save", SaveSession)
http.HandleFunc("/get", GetSession)
err := http.ListenAndServe(":8080", nil)
if err != nil {
fmt.Println("HTTP server failed,err:", err)
return
}
}

func SaveSession(w http.ResponseWriter, r *http.Request) {
// Get a session. We're ignoring the error resulted from decoding an
// existing session: Get() always returns a session, even if empty.

// 获取一个session对象,session-name是session的名字
session, err := store.Get(r, "session-name")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}

// 在session中存储值
session.Values["foo"] = "bar"
session.Values[42] = 43
// 保存更改
session.Save(r, w)
}
func GetSession(w http.ResponseWriter, r *http.Request) {
session, err := store.Get(r, "session-name")
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
return
}
foo := session.Values["foo"]
fmt.Println(foo)
}

删除session的值

1
2
3
4
// 删除
// 将session的最大存储时间设置为小于零的数即为删除
session.Options.MaxAge = -1
session.Save(r, w)
使用支付宝打赏
使用微信打赏

点击上方按钮,请我喝杯咖啡!

扫描二维码,分享此文章