在Gin框架中,使用ctx.SetCookie()
方法来设置Cookie。下面是一个具体的实现示例:
func setCookie(c *gin.Context) {
// 设置Cookie的参数和值
c.SetCookie("my_cookie", "example value", 3600, "/", "localhost", false, true)
// 其他逻辑
}
在这个例子中,我们使用c.SetCookie()
方法来设置Cookie。方法接收的参数如下:
- 第一个参数是Cookie的名称。
- 第二个参数是Cookie的值。
- 第三个参数是Cookie的过期时间(以秒为单位)。在这个例子中,设置Cookie的过期时间为3600秒(即1小时)。
- 第四个参数是Cookie的路径,指定Cookie可用的路径。在这个例子中,我们将其设置为根路径 “/”。
- 第五个参数是Cookie的域,指定Cookie可用的域名。在这个例子中,我们将其设置为 “localhost”,表示只能在本地测试环境使用。
- 第六个参数是一个布尔值,指示是否使用HTTPS发送Cookie。在这个例子中,我们将其设置为false。
- 第七个参数是一个布尔值,指示是否启用SameSite属性。在这个例子中,我们将其设置为true。
通过这样设置,即可在响应中将Cookie发送给客户端,客户端会自动存储并在后续的请求中发送回服务器。
视图(view template)
在控制器中 设置 Cookie 值;
func (con AdminControllers) Views(c *gin.Context) {
c.SetCookie("username", "王二妹", 3600, "/", "localhost", false, true)
c.HTML(http.StatusOK, "admin/views/index.html", gin.H{
"title": "views页面",
})
}
过期时间后cookie 是否存在?
答案: 当一个 Cookie 的过期时间到达后,浏览器将不再发送该 Cookie 到服务器。换句话说,该 Cookie 在浏览器中被认为是过期的,不再被浏览器传输。
尽管浏览器不再发送过期的 Cookie,但该 Cookie 可能仍然存在于客户端的 Cookie 存储中。不同的浏览器有不同的行为,有些浏览器会在过期后立即删除该 Cookie,而有些浏览器会保留该过期 Cookie 直到清除浏览器缓存或者用户主动删除它。
在服务器端的代码中,你无法直接检查客户端的 Cookie 存储。服务器只会接收到浏览器发送的有效 Cookie(即未过期的 Cookie)。
因此,即使过期时间已经到达,你仍然可以在服务器端收到过期的 Cookie,直到浏览器删除它为止。
为避免处理过期的 Cookie,可以在服务器端检查接收到的 Cookie 是否在有效期内,如果已经过期,则不对其进行进一步处理。
如何删除cookie 设置的字段?
在 Gin 框架中,要删除一个 Cookie,可以使用 c.SetCookie()
方法,并将其过期时间设置为一个过去的时间戳。这将使浏览器立即将该 Cookie 标记为过期并删除。
以下是一个示例:
func deleteCookie(c *gin.Context) {
// 删除名为 "my_cookie" 的 Cookie
c.SetCookie("my_cookie", "", -1, "/", "localhost", false, true)
// 其他逻辑
}
在这个例子中,我们使用 c.SetCookie()
方法来删除名为 “my_cookie” 的 Cookie。我们将 Cookie 的过期时间设置为 -1
,表示该 Cookie 已经过期。然后,我们将其他参数设置为与原始 Cookie 相同,确保浏览器删除正确的 Cookie。
通过这样的设置,当响应返回给客户端时,浏览器将立即删除名为 “my_cookie” 的 Cookie。
需要注意的是,要正确删除一个 Cookie,必须确保在 SetCookie 方法中的参数(例如路径、域名、Secure、SameSite)与设置 Cookie 时使用的参数完全一致。只有在这些参数完全匹配的情况下,浏览器才能正确识别并删除 Cookie。
总结一下,要删除一个 Cookie,设置它的过期时间为一个过去的时间戳,并在 c.SetCookie()
方法中使用与原始 Cookie 相同的参数。这将通知浏览器立即删除该 Cookie。
package admins
import (
"fmt"
"net/http"
"os"
"path"
"project/models"
"strconv"
"github.com/gin-gonic/gin"
)
type AdminControllers struct{}
func (con AdminControllers) Index(c *gin.Context) {
c.String(200, "admin后管项目")
}
func (con AdminControllers) PageIndex(c *gin.Context) {
c.HTML(200, "admin/login/index.html", gin.H{
"title": "admin后管项目",
})
}
func (con AdminControllers) Login(c *gin.Context) {
username := c.PostForm("username")
password := c.PostForm("password")
c.String(200, "用户名:=%v,密码:=%v \n", username, password)
// c.HTML(200, "admin/views/index.html", gin.H{
// "title": "viewAdmin页面",
// })
}
func (con AdminControllers) Register(c *gin.Context) {
c.HTML(200, "admin/register/index.html", gin.H{
"title": "注册页面",
})
}
func (con AdminControllers) Views(c *gin.Context) {
c.SetCookie("username", "王二妹", 3600, "/", "localhost", false, true)
c.SetCookie("hobby", "玩游戏,看电视", 5, "/", "localhost", false, true)
// c.String(200, "Views页面")
c.HTML(http.StatusOK, "admin/views/index.html", gin.H{
"title": "views页面",
})
}
func (con AdminControllers) DeteleCookie(c *gin.Context) {
username, err := c.Cookie("username")
// 获取名为 "my_cookie" 的 Cookie
if err == nil {
// 找到了名为 "my_cookie" 的 Cookie
// cookie 变量包含了该 Cookie 的值
fmt.Printf("username==success===%v \n", username)
} else {
// 没有找到名为 "my_cookie" 的 Cookie
c.String(200, "username==error===%v \n", err.Error())
}
c.SetCookie("username", "王二妹", -1, "/", "localhost", false, true)
c.HTML(http.StatusOK, "admin/views/index.html", gin.H{
"title": "views-detelecookie-successfuly",
"username": username,
})
}
需要 admin/views/
终端输出:
21:2:49 app | [GIN] 2023/06/30 - 21:02:49 | 200 | 7.0073ms | ::1 | GET "/admin/views"
21:2:55 app | username==success===王二妹
21:2:55 app | [GIN] 2023/06/30 - 21:02:55 | 200 | 5.0031ms | ::1 | GET "/admin/views/delete"
21:6:43 app | [GIN] 2023/06/30 - 21:06:43 | 200 | 6.0031ms | ::1 | GET "/admin/views"
21:8:38 app | username==success===王二妹
21:8:38 app | [GIN] 2023/06/30 - 21:08:38 | 200 | 7.0049ms | ::1 | GET "/admin/views/delete"
这里可以拓展一下 关于二级域名访问 cookie 的问题;
在localhost 本地环境下,C:\Windows\System32\drivers\etc 下host文件,修改一下映射文件;
127.0.0.1 文件。
这里就可以直观可以看见,修改后,不一样的二级域名也可以访问同样localhost下的cookie值。
关于Session的使用,更多是引入第三方包 (go get github.com/gin-contrib/sessions/cookie)
在代码上需要引入相对应的包,才可以在main()主入口文件注册对应的session中间件;
package main
// 引入但三方包 sessions/cookie
// go get github.com/gin-contrib/sessions/cookie
import (
"project/routers"
"github.com/gin-contrib/sessions"
"github.com/gin-contrib/sessions/cookie"
"github.com/gin-gonic/gin"
)
func main() {
r := gin.Default()
// Create template for router html template
r.LoadHTMLGlob("*templates/**/**/*")
// 主入口文件 注册 session 中间件
store := cookie.NewStore([]byte("secret")) // 设置 Session 密钥
r.Use(sessions.Sessions("mysession", store))
r.GET("/", func(ctx *gin.Context) {
ctx.JSON(200, gin.H{
"message": "Hello, world!",
})
})
routers.AdminRoutersInit(r)
routers.DefaultRoutersInit(r)
r.Run(":8081")
}
以上就是,注册成功了,在主入口文件main.go文件中注册成功。那么在全局其他地方也就是使用的范围呢?(通常在路由的对应控制器中去使用)
展示案例:
defaultControllers.go 文件
package defaults
import (
"github.com/gin-contrib/sessions"
"github.com/gin-gonic/gin"
)
type DefaultControllers struct {
}
func (con DefaultControllers) Index(c *gin.Context) {
// 创建 session 引擎 传入工作对象
session := sessions.Default(c)
// 设置过期时间
session.Options(sessions.Options{
MaxAge: 3600 * 6, // 6个小时。基础单位秒
})
session.Set("username", "xiaoxiao")
session.Save()
c.String(200, "default-index.html")
}
func (con DefaultControllers) Add(c *gin.Context) {
// 获取 session 值 username
session := sessions.Default(c)
username := session.Get("username")
c.String(200, "default==add.html===%v \n", username)
}
代码执行后输出结果: 路由走 /default 时候设置session值username,当路由走 /default/add时候路由过去设置的session值;
可以看出这里我们对于session的值是加密后的展示,我们如果感兴趣可以翻看 sessions的源码包查看。
备注:
1、sessions.Default(c) 这里就是生成一个sessions中间件的对象
2、session.Save()这个在设置时间必须要有,不然不生效。
同时,在调用 sessions时候,我们用的注册存储空间是cookie 这个容器,也可以用其他的存储空间容器,比如 redis ……
这个地方的容器 Redis 也是很好的选择。
希望对于你的学习有帮助!