初识 Cookie

HTTP 是无状态协议。简单地说,当你浏览了一个页面,然后转到同一个网站的另一个页 面,服务器无法认识到这是同一个浏览器在访问同一个网站。每一次的访问,都是没有任何关系的。如果我们要实现多个页面之间共享数据的话我们就可以使用 Cookie 或者 Session 实现

cookie 存储于访问者计算机的浏览器中,可以让我们用同一个浏览器访问同一个域名的时候共享数据

Cookie 能实现的简单功能:

  • 保持用户登录状态

  • 保存用户浏览记录


使用 Cookie

1
con.SetCookie(name string, value string, maxAge int, path string, domain string, secure bool, httpOnly bool)
  • maxAge:过期时间

    • 大于0,设置过期时间,单位为秒
    • 小于0,删除本Cookie
    • 等于0,设置为当关闭浏览器时过期
  • pathCookie的路径

  • domain:作用域,若要在多个二级域名中使用,如a.example.comb.example.com,则要写成.example.com

  • secure:为True时,仅在HTTPS中生效

  • httpOnly:用于防止客户端脚本通过document.cookie属性访问Cookie,有助于保护Cookie不被跨站脚本攻击窃取或篡改

1
cookie, err := con.Cookie("name")

样例

defaultRouters.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package routers

import (
"test/controllers/homePage"

"github.com/gin-gonic/gin"
)

func DefaultRoutersInit(r *gin.Engine) {
//前台路由
defaultRouters := r.Group("/")
{
defaultRouters.GET("/", homePage.HomePageController{}.Index)
defaultRouters.GET("/news", homePage.HomePageController{}.News)
defaultRouters.GET("/user", homePage.HomePageController{}.User)
defaultRouters.GET("/login", homePage.HomePageController{}.Login)
defaultRouters.GET("/logout", homePage.HomePageController{}.Logout)
}
}

homePageController.go

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
package homePage

import "github.com/gin-gonic/gin"

type HomePageController struct {
}

func (c HomePageController) Login(con *gin.Context) {
con.SetCookie("username", "张三", 3600, "/", "127.0.0.1", false, true)
con.String(200, "已登录")
}

func (c HomePageController) Logout(con *gin.Context) {
username, _ := con.Cookie("username")
con.SetCookie("username", username, -1, "/", "127.0.0.1", false, true)
}

func (c HomePageController) User(con *gin.Context) {
username, _ := con.Cookie("username")
con.String(200, "用户:"+username)
}

func (c HomePageController) Index(con *gin.Context) {
con.String(200, "首页")
}

func (c HomePageController) News(con *gin.Context) {
con.String(200, "新闻")
}


初识 Session

Session技术与Cookie类似,最大的不同是Cookie是存储在客户端的,而Session是存储在服务端的

当客户端浏览器第一次访问服务器并发送请求时,服务器端会创建一个 session 对象,生成 一个类似于 key,value 的键值对,然后将 value 保存到服务器 将 key(cookie)返回到浏览器(客户端)。浏览器下次访问时会携带 key(cookie),找到对应的 session(value)

安装 session 包

gin是不集成session的,只能用第三方的

1
go get github.com/gin-contrib/sessions

样例

main.go

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
package main

import (
"html/template"
"test/models"
"test/routers"

"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
"github.com/gin-gonic/gin"
)

func main() {

r := gin.Default()

r.SetFuncMap(template.FuncMap{
"unixToDate": models.UnixToDate,
})

r.LoadHTMLGlob("templates/**/*")

store := cookie.NewStore([]byte("123456"))
r.Use(sessions.Sessions("mysession", store))

//前台路由
routers.DefaultRoutersInit(r)
//后台路由
routers.AdminRoutersInit(r)
//api 路由
routers.ApiRoutersInit(r)

r.Run()
}

homePageController.go

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
package homePage

import (
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
)

type HomePageController struct {
}

func (c HomePageController) Login(con *gin.Context) {
// con.SetCookie("username", "张三", 0, "/", "127.0.0.1", false, true)
session := sessions.Default(con)
session.Options(sessions.Options{
MaxAge: 3600 * 6, //6h
})
session.Set("username", "张三")
session.Save()
con.String(200, "已登录")
}

func (c HomePageController) Logout(con *gin.Context) {
session := sessions.Default(con)
session.Clear()
session.Save()
}

func (c HomePageController) User(con *gin.Context) {
session := sessions.Default(con)
username := session.Get("username")
con.JSON(200, gin.H{
"username": username,
})
}

func (c HomePageController) Index(con *gin.Context) {
con.String(200, "首页")
}

func (c HomePageController) News(con *gin.Context) {
con.String(200, "新闻")
}