[golang gin框架] 5.Cookie以及Session

1.Cookie

(1).介绍

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

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

(2).Cookie 能实现的功能

1).保持用户登录状态

2).保存用户浏览的历史记录

3).电商网站的加入购物车

...

(3).设置和获取 Cookie,多个二级域名共享 cookie

参考文档:https://gin-gonic.com/zh-cn/docs/examples/cookie/

参考文章:https://blog.csdn.net/zhoupenghui168/article/details/128885820

设置 Cookie

c.SetCookie(name, value string, maxAge int, path, domain string, secure, httpOnly bool)
参数说明:
第一个参数 key
第二个参数 value
第三个参数 过期时间.如果只想设置 Cookie 的保存路径而不想设置存活时间,可以在第三个
参数中传递 nil
第四个参数 cookie 的路径
第五个参数 cookie 的路径 Domain 作用域 本地调试配置成 localhost , 正式上线配置成域名
第六个参数是 secure ,当 secure 值为 true 时,cookie 在 HTTP 中是无效,在 HTTPS 中
才有效
第七个参数 httpOnly,是微软对 COOKIE 做的扩展。如果在 COOKIE 中设置了“httpOnly”属性,
则通过程序(
JS 脚本、applet 等)将无法读取到 COOKIE 信息,防止 XSS 攻击产生

获取 Cookie

cookie, err := c.Cookie("name")

完整案例

package itying

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

type DefaultController struct {
    
}

func (con DefaultController) Index(c *gin.Context) {
    //设置cookie
    //3600 表示 多少秒过期
    c.SetCookie("username", "李四", 3600, "/", "127.0.0.1", false, true)

    //多个二级域名共享 cookie
    //1、分别把 a.gin.com 和 b.gin.com 解析到我们的服务器
    //2、我们想的是用户在 a.gin.com 中设置 Cookie 信息后在 b.gin.com 中获取刚才设置的
    //cookie,也就是实现多个二级域名共享 cookie
    //这时候的话我们就可以这样设置 cookie
    c.SetCookie("username", "李四", 3600, "/", "*.gin.com", false, true)
    c.HTML(http.StatusOK, "default/index.html",gin.H{
        "msg":"我是一个msg",
        "t": 1629788010,
    })
}

func (con DefaultController) News(c *gin.Context) {
    //获取cookie
    username, _ := c.Cookie("username")

    c.String(http.StatusOK, "新闻--cookie.username=" +username)
}

func (con DefaultController) Shop(c *gin.Context) {
    //获取cookie
    username, _ := c.Cookie("username")

    c.String(http.StatusOK, "shop--cookie.username=" +username)
}

//删除cookie
func (con DefaultController) DeleteCookie(c *gin.Context) {
    //删除cookie
    c.SetCookie("username", "李四", -1, "/", "127.0.0.1", false, true)
}

2.Session

(1).介绍

session 是另一种记录客户状态的机制,不同的是 Cookie 保存在客户端浏览器中,而 session
保存在服务器上

(2).Session 的工作流程

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

(3).Gin 中使用 Session

Gin 官方没有提供 Session 相关的文档,这个时候可以使用第三方的 Session 中间
件来实现: https://github.com/gin-contrib/sessions
gin-contrib/sessions 中间件支持的存储引擎:
• cookie
• memstore
• redis
• memcached
• mongodb

(4).基于 Cookie 存储 Session

1).安装 session 包:在main.go对应的目录下运行

go get github.com/gin-contrib/sessions

2).基本的 session 用法

main.go
package main

import (
    "fmt"
    "gindemo/models"
    "gindemo/routers"
    "github.com/gin-contrib/sessions"
    "github.com/gin-contrib/sessions/cookie"
    _ "github.com/gin-contrib/sessions/cookie"
    "github.com/gin-contrib/sessions/redis"
    "github.com/gin-gonic/gin"
    "html/template"
    "os"
    "path/filepath"
    "strings"
    "time"
)

func main() {
    //初始化路由,会设置默认中间件:engine.Use(Logger(), Recovery()),可以使用gin.New()来设置路由
    r := gin.Default()

    //创建基于cookie的存储引擎,secret11111参数是用于加密的密钥
    store := cookie.NewStore([]byte("secret11111"))
    //设置session中间件,参数mysession,指的是session的名字,也是cookie的名字
    //store是前面创建的存储引擎,我们可以替换成其他存储引擎
    r.Use(sessions.Sessions("mysession", store))

    //定义模板函数,必须在r.LoadHTMLGlob前面
    r.SetFuncMap(template.FuncMap{
        "UnixToTime": models.UnixToTime, //注册模板函数
        "Println":    Println,
    })
    //加载templates中所有模板文件, 使用不同目录下名称相同的模板,注意:一定要放在配置路由之前才得行
    //如果模板在多级目录里面的话需要这样配置 r.LoadHTMLGlob("templates/**/**/*") /** 表示目录
    //LoadHTMLGlob只能加载同一层级的文件
    //比如说使用router.LoadHTMLFile("/templates/**/*"),就只能加载/templates/admin/或者/templates/order/下面的文件
    //解决办法就是通过filepath.Walk来搜索/templates下的以.html结尾的文件,把这些html文件都加载一个数组中,然后用LoadHTMLFiles加载
    //r.LoadHTMLGlob("templates/**/*")
    var files []string
    filepath.Walk("./templates", func(path string, info os.FileInfo, err error) error {
        if strings.HasSuffix(path, ".html") {
            files = append(files, path)
        }
        return nil
    })
    r.LoadHTMLFiles(files...)

    //配置静态web目录 第一个参数表示路由,第二个参数表示映射的目录
    r.Static("/static", "./static")

    //分组路由文件
    routers.AdminRoutersInit(r)
    routers.ApiRoutersInit(r)
    routers.DefaultRoutersInit(r)
    r.Run() // 启动一个web服务
}
控制器设置,获取session
package itying

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

type DefaultController struct {
    
}

func (con DefaultController) Index(c *gin.Context) {
    //设置session
    session := sessions.Default(c)
    session.Set("username", "张1三")
    session.Save() // 设置session的时候必须调用

    c.HTML(http.StatusOK, "default/index.html",gin.H{
        "msg":"我是一个msg",
        "t": 1629788010,
    })
}

func (con DefaultController) News(c *gin.Context) {
    //获取session
    //初始化session对象
    session:=sessions.Default(c)
    //设置过期时间
    session.Options(sessions.Options{
        MaxAge:3600*6,//6hrs
    })
    username := session.Get("username")
    c.String(http.StatusOK, "新闻--session.username=%v" , username)
}

func (con DefaultController) Shop(c *gin.Context) {
    //获取cookie
    username, _ := c.Cookie("username")

    c.String(http.StatusOK, "shop--cookie.username=" +username)
}

//删除cookie
func (con DefaultController) DeleteCookie(c *gin.Context) {
    //删除cookie
    c.SetCookie("username", "李四", -1, "/", "127.0.0.1", false, true)
}

(5).基于Redis 存储Session

如果想将 session 数据保存到 redis 中,只要将 session 的存储引擎改成 redis 即可
使用 redis 作为存储引擎,
首先安装 redis 存储引擎的包
1).安装 redis 存储引擎包:在main.go对应的目录下运行
go get github.com/gin-contrib/sessions/redis
2).案例
main.go
package main

import (
    "fmt"
    "gindemo/models"
    "gindemo/routers"
    "github.com/gin-contrib/sessions"
    "github.com/gin-contrib/sessions/cookie"
    _ "github.com/gin-contrib/sessions/cookie"
    "github.com/gin-contrib/sessions/redis"
    "github.com/gin-gonic/gin"
    "html/template"
    "os"
    "path/filepath"
    "strings"
    "time"
)

func main() {
    //初始化路由,会设置默认中间件:engine.Use(Logger(), Recovery()),可以使用gin.New()来设置路由
    r := gin.Default()

    //初始化基于redis的存储引擎: 需要启动redis服务,不然会报错
    //参数说明:
    //自第1个参数-redis最大的空闲连接数
    //第2个参数-数通信协议tcp或者udp
    //第3个参数-redis地址,格式,host:port 第4个参数-redis密码
    //第5个参数-session加密密钥
    store,_:=redis.NewStore(10,"tcp","localhost:6379","",[]byte("secret"))
    r.Use(sessions.Sessions("mysession",store))

    //定义模板函数,必须在r.LoadHTMLGlob前面
    r.SetFuncMap(template.FuncMap{
        "UnixToTime": models.UnixToTime, //注册模板函数
        "Println":    Println,
    })
    //加载templates中所有模板文件, 使用不同目录下名称相同的模板,注意:一定要放在配置路由之前才得行
    //如果模板在多级目录里面的话需要这样配置 r.LoadHTMLGlob("templates/**/**/*") /** 表示目录
    //LoadHTMLGlob只能加载同一层级的文件
    //比如说使用router.LoadHTMLFile("/templates/**/*"),就只能加载/templates/admin/或者/templates/order/下面的文件
    //解决办法就是通过filepath.Walk来搜索/templates下的以.html结尾的文件,把这些html文件都加载一个数组中,然后用LoadHTMLFiles加载
    //r.LoadHTMLGlob("templates/**/*")
    var files []string
    filepath.Walk("./templates", func(path string, info os.FileInfo, err error) error {
        if strings.HasSuffix(path, ".html") {
            files = append(files, path)
        }
        return nil
    })
    r.LoadHTMLFiles(files...)

    //配置静态web目录 第一个参数表示路由,第二个参数表示映射的目录
    r.Static("/static", "./static")

    //分组路由文件
    routers.AdminRoutersInit(r)
    routers.ApiRoutersInit(r)
    routers.DefaultRoutersInit(r)
    r.Run() // 启动一个web服务
}
控制器设置,获取session
package itying

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

type DefaultController struct {
    
}

func (con DefaultController) Index(c *gin.Context) {
    //设置session
    session := sessions.Default(c)
    session.Set("username", "张1三")
    session.Save() // 设置session的时候必须调用

    c.HTML(http.StatusOK, "default/index.html",gin.H{
        "msg":"我是一个msg",
        "t": 1629788010,
    })
}

func (con DefaultController) News(c *gin.Context) {
    //获取session
    //初始化session对象
    session:=sessions.Default(c)
    //设置过期时间
    session.Options(sessions.Options{
        MaxAge:3600*6,//6hrs
    })
    username := session.Get("username")
    c.String(http.StatusOK, "新闻--session.username=%v" , username)
}

func (con DefaultController) Shop(c *gin.Context) {
    //获取cookie
    username, _ := c.Cookie("username")

    c.String(http.StatusOK, "shop--cookie.username=" +username)
}

//删除cookie
func (con DefaultController) DeleteCookie(c *gin.Context) {
    //删除cookie
    c.SetCookie("username", "李四", -1, "/", "127.0.0.1", false, true)
}
注意:在使用redis储存session时,需要运行redis程序,不然会报错

[上一节][golang gin框架] 4.自定义Model以及Gin 文件上传

[下一节][golang gin框架] 6.Gin GORM简介以及安装

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,我可以为您提供一些关于使用 Golang Gin 框架进行项目实战的建议。 首先,您需要安装 GolangGin 框架。安装过程可以参考官方文档进行操作。然后,您可以按照以下步骤进行项目实战: 1. 创建项目结构 在您的 GOPATH 目录下创建一个新的项目文件夹。通常情况下,您需要为项目创建以下子文件夹: ``` . ├── main.go ├── config │ ├── config.go │ └── ... ├── controller │ ├── home_controller.go │ └── ... ├── middleware │ ├── auth.go │ └── ... ├── model │ ├── user.go │ └── ... ├── router │ ├── router.go │ └── ... └── service ├── user_service.go └── ... ``` 2. 创建路由 在 router 文件夹中创建一个 router.go 文件,并编写以下代码: ```go package router import ( "github.com/gin-gonic/gin" "your-project/controller" "your-project/middleware" ) func SetupRouter() *gin.Engine { r := gin.Default() // 中间件 r.Use(middleware.AuthMiddleware()) // 路由 r.GET("/", controller.HomePageHandler) return r } ``` 在上面的代码中,我们使用了 gin 框架中的 gin.Default() 函数来创建一个默认的 gin.Engine 实例,并使用中间件来进行身份验证。然后我们定义了一个路由,将根路径映射到 HomePageHandler 方法。 3. 创建控制器 在 controller 文件夹中创建 home_controller.go 文件,并编写以下代码: ```go package controller import ( "github.com/gin-gonic/gin" "your-project/service" ) func HomePageHandler(c *gin.Context) { users := service.GetAllUsers() c.JSON(200, users) } ``` 在上面的代码中,我们定义了一个 HomePageHandler 方法,它接收一个 gin.Context 对象作为参数,并使用 service 层中的 GetAllUsers 函数获取所有用户的数据。然后我们使用 JSON 方法将数据以 JSON 格式返回给客户端。 4. 创建服务层 在 service 文件夹中创建 user_service.go 文件,并编写以下代码: ```go package service import "your-project/model" func GetAllUsers() []*model.User { // TODO: 查询数据库获取所有用户数据 return []*model.User{} } ``` 在上面的代码中,我们定义了一个 GetAllUsers 函数,它返回一个包含所有用户数据的切片。在实际项目中,我们需要查询数据库来获取这些数据。 5. 创建模型 在 model 文件夹中创建 user.go 文件,并编写以下代码: ```go package model type User struct { ID int `json:"id"` Name string `json:"name"` Age int `json:"age"` } ``` 在上面的代码中,我们定义了一个 User 结构体,它包含三个字段:ID、Name 和 Age。这些字段将用于存储每个用户的信息。 6. 创建配置文件 在 config 文件夹中创建 config.go 文件,并编写以下代码: ```go package config const ( DB_HOST = "localhost" DB_PORT = "3306" DB_USERNAME = "root" DB_PASSWORD = "password" DB_NAME = "your-database-name" ) ``` 在上面的代码中,我们定义了一些常量,用于存储数据库配置信息。这些常量将在连接数据库时使用。 7. 连接数据库 在 service 层中的 GetAllUsers 函数中,我们需要连接数据库来获取所有用户数据。可以使用以下代码来连接 MySQL 数据库: ```go package service import ( "database/sql" "fmt" "your-project/config" "your-project/model" ) func GetAllUsers() []*model.User { // 连接数据库 db, err := sql.Open("mysql", fmt.Sprintf("%s:%s@tcp(%s:%s)/%s", config.DB_USERNAME, config.DB_PASSWORD, config.DB_HOST, config.DB_PORT, config.DB_NAME, )) if err != nil { panic(err) } defer db.Close() // 查询所有用户数据 rows, err := db.Query("SELECT * FROM users") if err != nil { panic(err) } // 解析查询结果 users := []*model.User{} for rows.Next() { user := &model.User{} err := rows.Scan(&user.ID, &user.Name, &user.Age) if err != nil { panic(err) } users = append(users, user) } return users } ``` 在上面的代码中,我们使用 sql.Open 函数来打开 MySQL 数据库连接。然后我们使用 db.Query 函数来查询所有用户数据,并使用 rows.Scan 函数将查询结果解析为 User 结构体的切片。 以上就是使用 Golang Gin 框架进行项目实战的流程。当然,在实际项目中,您需要根据自己的需求进行相应的修改和扩展。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值